赞
踩
环境准备:
Nacos2.2.0集群搭建
版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
安装,配置nacos不多说
地址:Sentinel1.8.6:https://github.com/alibaba/Sentinel/releases/tag/1.8.6
解压后使用IDEA打开sentinel-dashboard
104行注释掉: test
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <!--<scope>test</scope>--> </dependency>
复制:
放入:
NacosConfigProperties.java
文件- package com.alibaba.csp.sentinel.dashboard.rule.nacos;
-
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- @Component
- @ConfigurationProperties(prefix = "sentinel.nacos")
- public class NacosConfigProperties {
- // nacos地址
- private String serverAddr;
- // nacos登录名
- private String username;
- // nacos 登录密码
- private String password;
- // nacos命名空间
- private String namespace;
-
- public String getServerAddr() {
- return serverAddr;
- }
-
- public void setServerAddr(String serverAddr) {
- this.serverAddr = serverAddr;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getNamespace() {
- return namespace;
- }
-
- public void setNamespace(String namespace) {
- this.namespace = namespace;
- }
- }
NacosConfig.java
文件- /*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.alibaba.csp.sentinel.dashboard.rule.nacos;
-
- import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
- import com.alibaba.csp.sentinel.datasource.Converter;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.nacos.api.PropertyKeyConst;
- import com.alibaba.nacos.api.config.ConfigFactory;
- import com.alibaba.nacos.api.config.ConfigService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import java.util.List;
- import java.util.Properties;
-
- /**
- * @author Eric Zhao
- * @since 1.4.0
- */
- @Configuration
- public class NacosConfig {
- // 注入刚新建的nacos配置文件
- @Autowired
- private NacosConfigProperties nacosConfigProperties;
-
- @Bean
- public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
- return JSON::toJSONString;
- }
-
- @Bean
- public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
- return s -> JSON.parseArray(s, FlowRuleEntity.class);
- }
-
- @Bean
- public ConfigService nacosConfigService() throws Exception {
- // 注释
- // return ConfigFactory.createConfigService("localhost");
- // 新增
- Properties properties = new Properties();
- properties.put(PropertyKeyConst.SERVER_ADDR,nacosConfigProperties.getServerAddr());
- properties.put(PropertyKeyConst.USERNAME,nacosConfigProperties.getUsername());
- properties.put(PropertyKeyConst.PASSWORD,nacosConfigProperties.getPassword());
- properties.put(PropertyKeyConst.NAMESPACE,nacosConfigProperties.getNamespace());
- return ConfigFactory.createConfigService(properties);
- }
- }
修改resources/app/scripts/directives/sidebar/sidebar.html
直接搜dashboard.flowV1
定位57行去掉V1
// 'FlowServiceV1' 替换为 'FlowServiceV2'
/dashboard/flow/
定位第101行let url = '/dashboard/flow/' + $scope.app; 替换为:let url = '/dashboard/v2/flow/' + $scope.app;
application.properties
新增配置- # 服务端口、控制台地址、名称
- server.port=9100
- csp.sentinel.dashboard.server=127.0.0.1:9100
- project.name=sentinel-dashboard
- # Nacos地址、账号、密码
- sentinel.nacos.serverAddr=192.168.20.128:8999
- sentinel.nacos.username=nacos
- sentinel.nacos.password=nacos
- # 默认命名空间就是 public,不用填写,填了public反而找不到,所以这个置空就行。
- sentinel.nacos.namespace=
效果:
第一步:
在【com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade】包下增加【DegradeRuleNacosProvider】类
- /*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.alibaba.csp.sentinel.dashboard.rule.nacos;
-
- import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
- import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
- import com.alibaba.csp.sentinel.datasource.Converter;
- import com.alibaba.csp.sentinel.util.StringUtil;
- import com.alibaba.nacos.api.config.ConfigService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
-
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * @author Eric Zhao
- * @since 1.4.0
- */
- @Component("flowRuleNacosProvider")
- public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
-
- @Autowired
- private ConfigService configService;
- @Autowired
- private Converter<String, List<FlowRuleEntity>> converter;
-
- @Override
- public List<FlowRuleEntity> getRules(String appName) throws Exception {
- String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
- NacosConfigUtil.GROUP_ID, 3000);
- if (StringUtil.isEmpty(rules)) {
- return new ArrayList<>();
- }
- return converter.convert(rules);
- }
- }
第二步:在【com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade】包下增加【DegradeRuleNacosPublisher】类
- /**
- * @author Eric Zhao
- * @since 1.4.0
- */
- @Component("flowRuleNacosPublisher")
- public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
-
- @Autowired
- private ConfigService configService;
- @Autowired
- private Converter<List<FlowRuleEntity>, String> converter;
-
- @Override
- public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
- AssertUtil.notEmpty(app, "app name cannot be empty");
- if (rules == null) {
- return;
- }
- configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
- NacosConfigUtil.GROUP_ID, converter.convert(rules));
- }
- }
第三步:改造
- /*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.alibaba.csp.sentinel.dashboard.controller;
-
- import java.util.Date;
- import java.util.List;
-
- import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
- import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
- import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
- import com.alibaba.csp.sentinel.dashboard.controller.v2.DegradeControllerV1;
- import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
- import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
- import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
- import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
- import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
- import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
- import com.alibaba.csp.sentinel.slots.block.RuleConstant;
- import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy;
- import com.alibaba.csp.sentinel.util.StringUtil;
-
- import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
- import com.alibaba.csp.sentinel.dashboard.domain.Result;
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.web.bind.annotation.DeleteMapping;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.PutMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.servlet.http.HttpServletRequest;
-
- /**
- * Controller regarding APIs of degrade rules. Refactored since 1.8.0.
- *
- * @author Carpenter Lee
- * @author Eric Zhao
- */
- @RestController
- @RequestMapping("/degrade")
- public class DegradeController {
-
- private final Logger logger = LoggerFactory.getLogger(DegradeController.class);
-
- @Autowired
- private RuleRepository<DegradeRuleEntity, Long> repository;
-
- @Autowired
- private AuthService<HttpServletRequest> authService;
-
- @Autowired
- @Qualifier("degradeRuleNacosProvider")
- private DynamicRuleProvider<List<DegradeRuleEntity>> ruleProvider;
-
- @Autowired
- @Qualifier("degradeRuleNacosPublisher")
- private DynamicRulePublisher<List<DegradeRuleEntity>> rulePublisher;
-
- @Autowired
- private SentinelApiClient sentinelApiClient;
-
- @GetMapping("/rules.json")
- @AuthAction(PrivilegeType.READ_RULE)
- public Result<List<DegradeRuleEntity>> apiQueryMachineRules(HttpServletRequest request, String app, String ip, Integer port) {
- AuthService.AuthUser authUser = authService.getAuthUser(request);
- authUser.authTarget(app, PrivilegeType.READ_RULE);
-
- if (StringUtil.isEmpty(app)) {
- return Result.ofFail(-1, "app can't be null or empty");
- }
- if (StringUtil.isEmpty(ip)) {
- return Result.ofFail(-1, "ip can't be null or empty");
- }
- if (port == null) {
- return Result.ofFail(-1, "port can't be null");
- }
- try {
- List<DegradeRuleEntity> rules = ruleProvider.getRules(app);
- rules = repository.saveAll(rules);
- return Result.ofSuccess(rules);
- } catch (Throwable throwable) {
- logger.error("queryApps error:", throwable);
- return Result.ofThrowable(-1, throwable);
- }
- }
-
- @PostMapping("/rule")
- @AuthAction(PrivilegeType.WRITE_RULE)
- public Result<DegradeRuleEntity> apiAddRule(@RequestBody DegradeRuleEntity entity) {
- Result<DegradeRuleEntity> checkResult = checkEntityInternal(entity);
- if (checkResult != null) {
- return checkResult;
- }
- Date date = new Date();
- entity.setGmtCreate(date);
- entity.setGmtModified(date);
- try {
- entity = repository.save(entity);
- publishRules(entity.getApp());
- } catch (Throwable t) {
- logger.error("Failed to add new degrade rule, app={}, ip={}", entity.getApp(), entity.getIp(), t);
- return Result.ofThrowable(-1, t);
- }
- return Result.ofSuccess(entity);
- }
-
- @PutMapping("/rule/{id}")
- @AuthAction(PrivilegeType.WRITE_RULE)
- public Result<DegradeRuleEntity> apiUpdateRule(@PathVariable("id") Long id,
- @RequestBody DegradeRuleEntity entity) {
- if (id == null || id <= 0) {
- return Result.ofFail(-1, "id can't be null or negative");
- }
- DegradeRuleEntity oldEntity = repository.findById(id);
- if (oldEntity == null) {
- return Result.ofFail(-1, "Degrade rule does not exist, id=" + id);
- }
- entity.setApp(oldEntity.getApp());
- entity.setIp(oldEntity.getIp());
- entity.setPort(oldEntity.getPort());
- entity.setId(oldEntity.getId());
- Result<DegradeRuleEntity> checkResult = checkEntityInternal(entity);
- if (checkResult != null) {
- return checkResult;
- }
- entity.setGmtCreate(oldEntity.getGmtCreate());
- entity.setGmtModified(new Date());
- try {
- entity = repository.save(entity);
- publishRules(entity.getApp());
- } catch (Throwable t) {
- logger.error("Failed to save degrade rule, id={}, rule={}", id, entity, t);
- return Result.ofThrowable(-1, t);
- }
- return Result.ofSuccess(entity);
- }
-
- @DeleteMapping("/rule/{id}")
- @AuthAction(PrivilegeType.DELETE_RULE)
- public Result<Long> delete(@PathVariable("id") Long id) {
- if (id == null) {
- return Result.ofFail(-1, "id can't be null");
- }
-
- DegradeRuleEntity oldEntity = repository.findById(id);
- if (oldEntity == null) {
- return Result.ofSuccess(null);
- }
-
- try {
- repository.delete(id);
- publishRules(oldEntity.getApp());
- } catch (Throwable throwable) {
- logger.error("Failed to delete degrade rule, id={}", id, throwable);
- return Result.ofThrowable(-1, throwable);
- }
- return Result.ofSuccess(id);
- }
-
- private void publishRules(String app) throws Exception {
- List<DegradeRuleEntity> rules = repository.findAllByApp(app);
- rulePublisher.publish(app, rules);
- }
-
-
- private <R> Result<R> checkEntityInternal(DegradeRuleEntity entity) {
- if (StringUtil.isBlank(entity.getApp())) {
- return Result.ofFail(-1, "app can't be blank");
- }
- if (StringUtil.isBlank(entity.getIp())) {
- return Result.ofFail(-1, "ip can't be null or empty");
- }
- if (entity.getPort() == null || entity.getPort() <= 0) {
- return Result.ofFail(-1, "invalid port: " + entity.getPort());
- }
- if (StringUtil.isBlank(entity.getLimitApp())) {
- return Result.ofFail(-1, "limitApp can't be null or empty");
- }
- if (StringUtil.isBlank(entity.getResource())) {
- return Result.ofFail(-1, "resource can't be null or empty");
- }
- Double threshold = entity.getCount();
- if (threshold == null || threshold < 0) {
- return Result.ofFail(-1, "invalid threshold: " + threshold);
- }
- Integer recoveryTimeoutSec = entity.getTimeWindow();
- if (recoveryTimeoutSec == null || recoveryTimeoutSec <= 0) {
- return Result.ofFail(-1, "recoveryTimeout should be positive");
- }
- Integer strategy = entity.getGrade();
- if (strategy == null) {
- return Result.ofFail(-1, "circuit breaker strategy cannot be null");
- }
- if (strategy < CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType()
- || strategy > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
- return Result.ofFail(-1, "Invalid circuit breaker strategy: " + strategy);
- }
- if (entity.getMinRequestAmount() == null || entity.getMinRequestAmount() <= 0) {
- return Result.ofFail(-1, "Invalid minRequestAmount");
- }
- if (entity.getStatIntervalMs() == null || entity.getStatIntervalMs() <= 0) {
- return Result.ofFail(-1, "Invalid statInterval");
- }
- if (strategy == RuleConstant.DEGRADE_GRADE_RT) {
- Double slowRatio = entity.getSlowRatioThreshold();
- if (slowRatio == null) {
- return Result.ofFail(-1, "SlowRatioThreshold is required for slow request ratio strategy");
- } else if (slowRatio < 0 || slowRatio > 1) {
- return Result.ofFail(-1, "SlowRatioThreshold should be in range: [0.0, 1.0]");
- }
- } else if (strategy == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) {
- if (threshold > 1) {
- return Result.ofFail(-1, "Ratio threshold should be in range: [0.0, 1.0]");
- }
- }
- return null;
- }
- }
第四步:添加应用服务配置,注意不是sentinel服务的配置。
--- #################### Sentinel配置 #################### spring: cloud: # Sentinel 配置项,对应 SentinelProperties 配置属性类 sentinel: enabled: true # 是否开启。默认为 true 开启 eager: true # 是否饥饿加载。默认为 false 关闭 transport: dashboard: 10.205.30.1:7070 # Sentinel 控制台地址 filter: url-patterns: /** # 拦截请求的地址。默认为 /* datasource: flow: nacos: server-addr: 10.30.225.112:8848 username: nacos password: nacos namespace: test dataId: operation-server-flow-rules groupId: DEFAULT_GROUP rule-type: flow data-type: json degrade: nacos: server-addr: 10.30.225.112:8848 username: nacos password: nacos namespace: test dataId: operation-server-degrade-rules groupId: DEFAULT_GROUP rule-type: degrade data-type: json
效果:
11.热点,系统,授权同熔断规则
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。