当前位置: 首页 > news >正文

网站当前链接化妆品销售网站开发与设计

网站当前链接,化妆品销售网站开发与设计,公司公司网站建设,梁头网站建设文章目录一、前言1. 版本选取2. 克隆代码3. 导入 IDEA二、全局修改2.1. 修改 POM2.2. 修改配置文件三、后端代码修改3.1. 包结构部分3.2. nacos 配置文件四、创建规则与 Nacos 交互类4.1. 创建授权规则与 Nacos 交互类4.2. 创建降级规则与 Nacos 交互类4.3. 创建流控规则与 Nac… 文章目录一、前言1. 版本选取2. 克隆代码3. 导入 IDEA二、全局修改2.1. 修改 POM2.2. 修改配置文件三、后端代码修改3.1. 包结构部分3.2. nacos 配置文件四、创建规则与 Nacos 交互类4.1. 创建授权规则与 Nacos 交互类4.2. 创建降级规则与 Nacos 交互类4.3. 创建流控规则与 Nacos 交互类4.4. 创建网关流控规则与 Nacos 交互类4.5. 创建热点规则与 Nacos 交互类4.6. 创建系统规则与 Nacos 交互类五、控制层修改5.1. AuthorityRuleController5.2. DegradeController5.3. FlowControllerV25.4. GatewayApiController5.5. GatewayFlowRuleController5.6. ParamFlowRuleController5.7. SystemController六、前端代码调整6.1. sidebar.html6.2. flow_service_v1.js6.3. identity.js6.4. flow_v2.html七、修改的文件总览7.1. 后端文件列表7.2. 前端文件列表八、编译打包8.1. 编译前端8.2. 编译打包后端九、测试验证9.1. 版本选取9.2. 启动nacos9.3. 启动sentinel-dashboard9.4. 添加流控规则9.5. 重启sentinel-dashboard9.6. 删除流控规则9.7. nacos删除流控规则9.8. nacos修改流控规则9.9. 测试结论十、微服务集成10.1. pom依赖引入10.2. sentinel规则持久化配置10.3. nacos效果图一、前言 1. 版本选取 要想改造 sentinel-dashboard需要修改 dashboard 的源码。本文基于sentinel 1.8.2 2. 克隆代码 先通过 Github 拉取 Sentinel 源码GitHub 地址https://github.com/alibaba/Sentinel 3. 导入 IDEA 下载依赖进入 sentinel-dashboard 模块所有的修改都在该模块下。 二、全局修改 2.1. 修改 POM 想要将 dashboard 的规则持久化到 Nacos需要添加一个依赖源码中已经添加不过只在测试环境下打包进去了。 在 pom.xml 文件中找到以下依赖去掉 scope 或注释掉。 !-- for Nacos rule publisher sample -- dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId!-- scopetest/scope -- /dependency2.2. 修改配置文件 找到配置文件 application.properties 文件在末尾添加一下配置 #Nacos Configurations sentinel.nacos.serverAddrlocalhost:8848 sentinel.nacos.namespace sentinel.nacos.group-idSENTINEL-GROUP注sentinel.nacos.serverAddr 是 Nacos 服务器地址如果是集群则用逗号隔开 三、后端代码修改 3.1. 包结构部分 新建包 com.alibaba.csp.sentinel.dashboard.rule.nacos并在该包下根据以下结构新建包 ├─auth #存放授权规则相关类 ├─degrade #存放降级规则相关类 ├─flow #存放限流规则相关类 ├─gateway #存放网关限流规则相关类 │ ├─api │ └─flow ├─param #存放热点规则相关类 └─system #存放系统规则相关类 3.2. nacos 配置文件 直接在com.alibaba.csp.sentinel.dashboard.rule.nacos包下创建以下类 ①NacosPropertiesConfig存放前面配置文件中关于 Nacos 的配置 package com.alibaba.csp.sentinel.dashboard.rule.nacos;import org.springframework.boot.context.properties.ConfigurationProperties;/*** author gblfy* date 2021-08-05*/ ConfigurationProperties(sentinel.nacos) public class NacosPropertiesConfig {private String serverAddr;private String dataId;private String groupId SENTINEL_GROUP; // 默认分组private String namespace;public String getServerAddr() {return serverAddr;}public void setServerAddr(String serverAddr) {this.serverAddr serverAddr;}public String getDataId() {return dataId;}public void setDataId(String dataId) {this.dataId dataId;}public String getGroupId() {return groupId;}public void setGroupId(String groupId) {this.groupId groupId;}public String getNamespace() {return namespace;}public void setNamespace(String namespace) {this.namespace namespace;} } ②NacosConfigUtil存放一些常量各种规则文件名后缀。 package com.alibaba.csp.sentinel.dashboard.rule.nacos;/*** author gblfy* date 2021-08-05*/ public final class NacosConfigUtil {public static final String GROUP_ID SENTINEL_GROUP;public static final String FLOW_DATA_ID_POSTFIX -flow-rules;public static final String DEGRADE_DATA_ID_POSTFIX -degrade-rules;public static final String PARAM_FLOW_DATA_ID_POSTFIX -param-rules;public static final String SYS_DATA_ID_POSTFIX -system-rules;public static final String AUTH_DATA_ID_POSTFIX -auth-rules;public static final String GATEWAY_FLOW_DATA_ID_POSTFIX -gateway-flow;public static final String GATEWAY_API_DATA_ID_POSTFIX -gateway-api;public static final String CLUSTER_MAP_DATA_ID_POSTFIX -cluster-map;/*** cc for cluster-client*/public static final String CLIENT_CONFIG_DATA_ID_POSTFIX -cc-config;/*** cs for cluster-server*/public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX -cs-transport-config;public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX -cs-flow-config;public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX -cs-namespace-set;private NacosConfigUtil() {} } ③ NacosConfig package com.alibaba.csp.sentinel.dashboard.rule.nacos;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.*; 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.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.List; import java.util.Properties;/*** author gblfy* date 2021-08-05*/ EnableConfigurationProperties(NacosPropertiesConfig.class) Configuration public class NacosConfig {//流控规则 ConverterBeanpublic ConverterListFlowRuleEntity, String flowRuleEntityEncoder() {return JSON::toJSONString;}Beanpublic ConverterString, ListFlowRuleEntity flowRuleEntityDecoder() {return s - JSON.parseArray(s, FlowRuleEntity.class);}//降级规则 ConverterBeanpublic ConverterListDegradeRuleEntity, String degradeRuleEntityEncoder() {return JSON::toJSONString;}Beanpublic ConverterString, ListDegradeRuleEntity degradeRuleEntityDecoder() {return s - JSON.parseArray(s, DegradeRuleEntity.class);}//热点规则 ConverterBeanpublic ConverterListParamFlowRuleEntity, String paramsRuleEntityEncoder() {return JSON::toJSONString;}Beanpublic ConverterString, ListParamFlowRuleEntity paramsRuleEntityDecoder() {return s - JSON.parseArray(s, ParamFlowRuleEntity.class);}//系统规则 ConverterBeanpublic ConverterListSystemRuleEntity, String systemRuleEntityEncoder() {return JSON::toJSONString;}Beanpublic ConverterString, ListSystemRuleEntity systemRuleEntityDecoder() {return s - JSON.parseArray(s, SystemRuleEntity.class);}//授权规则 ConverterBeanpublic ConverterListAuthorityRuleEntity, String authRuleEntityEncoder() {return JSON::toJSONString;}BeanConverterString, ListAuthorityRuleEntity authRuleEntityDecoder() {return s - JSON.parseArray(s, AuthorityRuleEntity.class);}//网关限流规则 ConverterBeanpublic ConverterListGatewayFlowRuleEntity, String gatewayFlowRuleEntityEncoder() {return JSON::toJSONString;}BeanConverterString, ListGatewayFlowRuleEntity gatewayFlowRuleEntityDecoder() {return s - JSON.parseArray(s, GatewayFlowRuleEntity.class);}//网关API限流规则 ConverterBeanpublic ConverterListApiDefinitionEntity, String gatewayApiRuleEntityEncoder() {return JSON::toJSONString;}BeanConverterString, ListApiDefinitionEntity gatewayApiRuleEntityDecoder() {return s - JSON.parseArray(s, ApiDefinitionEntity.class);}Beanpublic ConfigService nacosConfigService(NacosPropertiesConfig nacosPropertiesConfig) throws Exception {Properties properties new Properties();properties.put(PropertyKeyConst.SERVER_ADDR, nacosPropertiesConfig.getServerAddr());properties.put(PropertyKeyConst.NAMESPACE, nacosPropertiesConfig.getNamespace());return ConfigFactory.createConfigService(properties);} } 四、创建规则与 Nacos 交互类 4.1. 创建授权规则与 Nacos 交互类 在前面创建的auth包下创建以下两个类 AuthorityRuleNacosProvider ①AuthorityRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.auth;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.nacos.api.config.ConfigService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.ArrayList; import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(authRuleNacosProvider) public class AuthorityRuleNacosProvider implements DynamicRuleProviderListAuthorityRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(AuthorityRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListAuthorityRuleEntity converter;Overridepublic ListAuthorityRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.AUTH_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get auth rule from nacos, rules : {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②AuthorityRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.auth;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(authRuleNacosPublisher) public class AuthorityRuleNacosPublisher implements DynamicRulePublisherListAuthorityRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(AuthorityRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListAuthorityRuleEntity, String converter;Overridepublic void publish(String app, ListAuthorityRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publisher auth rules : {}, convertedRule);configService.publishConfig(app NacosConfigUtil.AUTH_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 4.2. 创建降级规则与 Nacos 交互类 和前面一样在前面创建的degrade包下创建以下两个类 ①DegradeRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; 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;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(degradeRuleNacosProvider) public class DegradeRuleNacosProvider implements DynamicRuleProviderListDegradeRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(DegradeRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListDegradeRuleEntity converter;Overridepublic ListDegradeRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get degrade rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②DegradeRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.List;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(degradeRuleNacosPublisher) public class DegradeRuleNacosPublisher implements DynamicRulePublisherListDegradeRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(DegradeRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListDegradeRuleEntity, String converter;Overridepublic void publish(String app, ListDegradeRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publish degrade rules: {}, convertedRule);configService.publishConfig(app NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 4.3. 创建流控规则与 Nacos 交互类 在前面创建的flow包下创建以下两个类 ①FlowRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.nacos.api.config.ConfigService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.ArrayList; import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(flowRuleNacosProvider) public class FlowRuleNacosProvider implements DynamicRuleProviderListFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(FlowRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListFlowRuleEntity converter;Overridepublic ListFlowRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get flow rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②FlowRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(flowRuleNacosPublisher) public class FlowRuleNacosPublisher implements DynamicRulePublisherListFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(FlowRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListFlowRuleEntity, String converter;Overridepublic void publish(String app, ListFlowRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publish flow rules: {}, convertedRule);configService.publishConfig(app NacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 4.4. 创建网关流控规则与 Nacos 交互类 在前面创建的gateway.api包下创建以下两个类 ①GatewayApiRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; 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;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(gatewayApiRuleNacosProvider) public class GatewayApiRuleNacosProvider implements DynamicRuleProviderListApiDefinitionEntity {private static final Logger LOGGER LoggerFactory.getLogger(GatewayApiRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListApiDefinitionEntity converter;Overridepublic ListApiDefinitionEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.GATEWAY_API_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get gateway api rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②GatewayApiRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.List;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(gatewayApiRuleNacosPublisher) public class GatewayApiRuleNacosPublisher implements DynamicRulePublisherListApiDefinitionEntity {private static final Logger LOGGER LoggerFactory.getLogger(GatewayApiRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListApiDefinitionEntity, String converter;Overridepublic void publish(String app, ListApiDefinitionEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publish gateway api rules: {}, convertedRule);configService.publishConfig(app NacosConfigUtil.GATEWAY_API_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 在gateway.flow包下创建以下两个类 ①GatewayFlowRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; 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;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(gatewayFlowRuleNacosProvider) public class GatewayFlowRuleNacosProvider implements DynamicRuleProviderListGatewayFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(GatewayFlowRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListGatewayFlowRuleEntity converter;Overridepublic ListGatewayFlowRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get gateway flow rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②GatewayFlowRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.List;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(gatewayFlowRuleNacosPublisher) public class GatewayFlowRuleNacosPublisher implements DynamicRulePublisherListGatewayFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(GatewayFlowRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListGatewayFlowRuleEntity, String converter;Overridepublic void publish(String app, ListGatewayFlowRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publish gateway flow rules: {}, convertedRule);configService.publishConfig(app NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 4.5. 创建热点规则与 Nacos 交互类 在前面创建的param包下新建以下两个类 ParamRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.param;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;import java.util.ArrayList; import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(paramRuleNacosProvider) public class ParamRuleNacosProvider implements DynamicRuleProviderListParamFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(ParamRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListParamFlowRuleEntity converter;Overridepublic ListParamFlowRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get param rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ParamRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.param;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(paramRuleNacosPublisher) public class ParamRuleNacosPublisher implements DynamicRulePublisherListParamFlowRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(ParamRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListParamFlowRuleEntity, String converter;Overridepublic void publish(String app, ListParamFlowRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publish param rules: {}, convertedRule);configService.publishConfig(app NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);}} 4.6. 创建系统规则与 Nacos 交互类 在前面创建的system包下新建以下两个类 ①SystemRuleNacosProvider内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.system;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; 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;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;/*** author gblfy* date 2021-08-05*/ Component(systemRuleNacosProvider) public class SystemRuleNacosProvider implements DynamicRuleProviderListSystemRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(SystemRuleNacosProvider.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterString, ListSystemRuleEntity converter;Overridepublic ListSystemRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName NacosConfigUtil.SYS_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);LOGGER.info(get system rules from nacos, rules: {}, rules);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return converter.convert(rules);} } ②SystemRuleNacosPublisher内容如下 package com.alibaba.csp.sentinel.dashboard.rule.nacos.system;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil; import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.csp.sentinel.datasource.Converter;import java.util.List;/*** author gblfy* date 2021-08-05*/ Component(systemRuleNacosPublisher) public class SystemRuleNacosPublisher implements DynamicRulePublisherListSystemRuleEntity {private static final Logger LOGGER LoggerFactory.getLogger(SystemRuleNacosPublisher.class);Autowiredprivate ConfigService configService;Autowiredprivate ConverterListSystemRuleEntity, String converter;Overridepublic void publish(String app, ListSystemRuleEntity rules) throws Exception {AssertUtil.notEmpty(app, app name cannot be empty);if (rules null) {return;}String convertedRule converter.convert(rules);LOGGER.info(sentinel dashboard publisher system rule : {}, convertedRule);configService.publishConfig(app NacosConfigUtil.SYS_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, convertedRule);} } 五、控制层修改 修改 Controller 5.1. AuthorityRuleController 修改 com.alibaba.csp.sentinel.dashboard.controller包下的AuthorityRuleController内容如下 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.client.SentinelApiClient; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; 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.util.StringUtil;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; import com.alibaba.csp.sentinel.dashboard.domain.Result; import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;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.RequestParam; import org.springframework.web.bind.annotation.RestController;/*** author Eric Zhao* since 0.2.1*/ RestController RequestMapping(value /authority) public class AuthorityRuleController {private final Logger logger LoggerFactory.getLogger(AuthorityRuleController.class);Autowiredprivate SentinelApiClient sentinelApiClient;Autowiredprivate RuleRepositoryAuthorityRuleEntity, Long repository;AutowiredQualifier(authRuleNacosProvider)private DynamicRuleProviderListAuthorityRuleEntity ruleProvider;AutowiredQualifier(authRuleNacosPublisher)private DynamicRulePublisherListAuthorityRuleEntity rulePublisher;GetMapping(/rules)AuthAction(PrivilegeType.READ_RULE)public ResultListAuthorityRuleEntity apiQueryAllRulesForMachine(RequestParam String app,RequestParam String ip,RequestParam Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cannot be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cannot be null or empty);}if (port null || port 0) {return Result.ofFail(-1, Invalid parameter: port);}try { // ListAuthorityRuleEntity rules sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);ListAuthorityRuleEntity rules ruleProvider.getRules(app);repository.saveAll(rules);return Result.ofSuccess(rules);} catch (Throwable throwable) {logger.error(Error when querying authority rules, throwable);return Result.ofFail(-1, throwable.getMessage());}}private R ResultR checkEntityInternal(AuthorityRuleEntity entity) {if (entity null) {return Result.ofFail(-1, bad rule body);}if (StringUtil.isBlank(entity.getApp())) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isBlank(entity.getIp())) {return Result.ofFail(-1, ip cant be null or empty);}if (entity.getPort() null || entity.getPort() 0) {return Result.ofFail(-1, port cant be null);}if (entity.getRule() null) {return Result.ofFail(-1, rule cant be null);}if (StringUtil.isBlank(entity.getResource())) {return Result.ofFail(-1, resource name cannot be null or empty);}if (StringUtil.isBlank(entity.getLimitApp())) {return Result.ofFail(-1, limitApp should be valid);}if (entity.getStrategy() ! RuleConstant.AUTHORITY_WHITE entity.getStrategy() ! RuleConstant.AUTHORITY_BLACK) {return Result.ofFail(-1, Unknown strategy (must be blacklist or whitelist));}return null;}PostMapping(/rule)AuthAction(PrivilegeType.WRITE_RULE)public ResultAuthorityRuleEntity apiAddAuthorityRule(RequestBody AuthorityRuleEntity entity) {ResultAuthorityRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}entity.setId(null);Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(Failed to add authority rule, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.info(Publish authority rules failed after rule add);}return Result.ofSuccess(entity);}PutMapping(/rule/{id})AuthAction(PrivilegeType.WRITE_RULE)public ResultAuthorityRuleEntity apiUpdateParamFlowRule(PathVariable(id) Long id,RequestBody AuthorityRuleEntity entity) {if (id null || id 0) {return Result.ofFail(-1, Invalid id);}ResultAuthorityRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}entity.setId(id);Date date new Date();entity.setGmtCreate(null);entity.setGmtModified(date);try {entity repository.save(entity);if (entity null) {return Result.ofFail(-1, Failed to save authority rule);}} catch (Throwable throwable) {logger.error(Failed to save authority rule, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.info(Publish authority rules failed after rule update);}return Result.ofSuccess(entity);}DeleteMapping(/rule/{id})AuthAction(PrivilegeType.DELETE_RULE)public ResultLong apiDeleteRule(PathVariable(id) Long id) {if (id null) {return Result.ofFail(-1, id cannot be null);}AuthorityRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);} catch (Exception e) {return Result.ofFail(-1, e.getMessage());}if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.error(Publish authority rules failed after rule delete);}return Result.ofSuccess(id);}private boolean publishRules(String app, String ip, Integer port) {ListAuthorityRuleEntity rules repository.findAllByMachine(MachineInfo.of(app, ip, port)); // return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules);try {rulePublisher.publish(app, rules);return true;} catch (Exception e) {return false;}} }主要是将SentinelApiClient相关调用改为我们前面创建的一系列NacosProvider和NacosPublisher类中的调用与 Nacos 交互。 5.2. DegradeController 修改 com.alibaba.csp.sentinel.dashboard.controller包下的DegradeController内容如下 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.client.SentinelApiClient; 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;/*** 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);Autowiredprivate RuleRepositoryDegradeRuleEntity, Long repository;Autowiredprivate SentinelApiClient sentinelApiClient;AutowiredQualifier(degradeRuleNacosProvider)private DynamicRuleProviderListDegradeRuleEntity ruleProvider;AutowiredQualifier(degradeRuleNacosPublisher)private DynamicRulePublisherListDegradeRuleEntity rulePublisher;GetMapping(/rules.json)AuthAction(PrivilegeType.READ_RULE)public ResultListDegradeRuleEntity apiQueryMachineRules(String app, String ip, Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cant be null or empty);}if (port null) {return Result.ofFail(-1, port cant be null);}try { // ListDegradeRuleEntity rules sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);ListDegradeRuleEntity 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 ResultDegradeRuleEntity apiAddRule(RequestBody DegradeRuleEntity entity) {ResultDegradeRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable t) {logger.error(Failed to add new degrade rule, app{}, ip{}, entity.getApp(), entity.getIp(), t);return Result.ofThrowable(-1, t);}if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.warn(Publish degrade rules failed, app{}, entity.getApp());}return Result.ofSuccess(entity);}PutMapping(/rule/{id})AuthAction(PrivilegeType.WRITE_RULE)public ResultDegradeRuleEntity apiUpdateRule(PathVariable(id) Long id,RequestBody DegradeRuleEntity entity) {if (id null || id 0) {return Result.ofFail(-1, id cant 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());ResultDegradeRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}entity.setGmtCreate(oldEntity.getGmtCreate());entity.setGmtModified(new Date());try {entity repository.save(entity);} catch (Throwable t) {logger.error(Failed to save degrade rule, id{}, rule{}, id, entity, t);return Result.ofThrowable(-1, t);}if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.warn(Publish degrade rules failed, app{}, entity.getApp());}return Result.ofSuccess(entity);}DeleteMapping(/rule/{id})AuthAction(PrivilegeType.DELETE_RULE)public ResultLong delete(PathVariable(id) Long id) {if (id null) {return Result.ofFail(-1, id cant be null);}DegradeRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);} catch (Throwable throwable) {logger.error(Failed to delete degrade rule, id{}, id, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.warn(Publish degrade rules failed, app{}, oldEntity.getApp());}return Result.ofSuccess(id);}private boolean publishRules(String app, String ip, Integer port) {ListDegradeRuleEntity rules repository.findAllByMachine(MachineInfo.of(app, ip, port)); // return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);try{rulePublisher.publish(app, rules);return true;}catch (Exception e){return false;}}private R ResultR checkEntityInternal(DegradeRuleEntity entity) {if (StringUtil.isBlank(entity.getApp())) {return Result.ofFail(-1, app cant be blank);}if (StringUtil.isBlank(entity.getIp())) {return Result.ofFail(-1, ip cant 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 cant be null or empty);}if (StringUtil.isBlank(entity.getResource())) {return Result.ofFail(-1, resource cant 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;} } 5.3. FlowControllerV2 修改 com.alibaba.csp.sentinel.dashboard.controller.v2包下的FlowControllerV2内容如下 package com.alibaba.csp.sentinel.dashboard.controller.v2;import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit;import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.util.StringUtil;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemoryRuleRepositoryAdapter; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; 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.RequestParam; import org.springframework.web.bind.annotation.RestController;/*** Flow rule controller (v2).** author Eric Zhao* since 1.4.0*/ RestController RequestMapping(value /v2/flow) public class FlowControllerV2 {private final Logger logger LoggerFactory.getLogger(FlowControllerV2.class);Autowiredprivate InMemoryRuleRepositoryAdapterFlowRuleEntity repository;// Autowired // Qualifier(flowRuleDefaultProvider) // private DynamicRuleProviderListFlowRuleEntity ruleProvider; // Autowired // Qualifier(flowRuleDefaultPublisher) // private DynamicRulePublisherListFlowRuleEntity rulePublisher;//注入Nacos Provider和 PublisherAutowiredQualifier(flowRuleNacosProvider)private DynamicRuleProviderListFlowRuleEntity ruleProvider;AutowiredQualifier(flowRuleNacosPublisher)private DynamicRulePublisherListFlowRuleEntity rulePublisher;GetMapping(/rules)AuthAction(PrivilegeType.READ_RULE)public ResultListFlowRuleEntity apiQueryMachineRules(RequestParam String app) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cant be null or empty);}try {ListFlowRuleEntity rules ruleProvider.getRules(app);if (rules ! null !rules.isEmpty()) {for (FlowRuleEntity entity : rules) {entity.setApp(app);if (entity.getClusterConfig() ! null entity.getClusterConfig().getFlowId() ! null) {entity.setId(entity.getClusterConfig().getFlowId());}}}rules repository.saveAll(rules);return Result.ofSuccess(rules);} catch (Throwable throwable) {logger.error(Error when querying flow rules, throwable);return Result.ofThrowable(-1, throwable);}}private R ResultR checkEntityInternal(FlowRuleEntity entity) {if (entity null) {return Result.ofFail(-1, invalid body);}if (StringUtil.isBlank(entity.getApp())) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isBlank(entity.getLimitApp())) {return Result.ofFail(-1, limitApp cant be null or empty);}if (StringUtil.isBlank(entity.getResource())) {return Result.ofFail(-1, resource cant be null or empty);}if (entity.getGrade() null) {return Result.ofFail(-1, grade cant be null);}if (entity.getGrade() ! 0 entity.getGrade() ! 1) {return Result.ofFail(-1, grade must be 0 or 1, but entity.getGrade() got);}if (entity.getCount() null || entity.getCount() 0) {return Result.ofFail(-1, count should be at lease zero);}if (entity.getStrategy() null) {return Result.ofFail(-1, strategy cant be null);}if (entity.getStrategy() ! 0 StringUtil.isBlank(entity.getRefResource())) {return Result.ofFail(-1, refResource cant be null or empty when strategy!0);}if (entity.getControlBehavior() null) {return Result.ofFail(-1, controlBehavior cant be null);}int controlBehavior entity.getControlBehavior();if (controlBehavior 1 entity.getWarmUpPeriodSec() null) {return Result.ofFail(-1, warmUpPeriodSec cant be null when controlBehavior1);}if (controlBehavior 2 entity.getMaxQueueingTimeMs() null) {return Result.ofFail(-1, maxQueueingTimeMs cant be null when controlBehavior2);}if (entity.isClusterMode() entity.getClusterConfig() null) {return Result.ofFail(-1, cluster config should be valid);}return null;}PostMapping(/rule)AuthAction(value AuthService.PrivilegeType.WRITE_RULE)public ResultFlowRuleEntity apiAddFlowRule(RequestBody FlowRuleEntity entity) {ResultFlowRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}entity.setId(null);Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);entity.setLimitApp(entity.getLimitApp().trim());entity.setResource(entity.getResource().trim());try {entity repository.save(entity);publishRules(entity.getApp());} catch (Throwable throwable) {logger.error(Failed to add flow rule, throwable);return Result.ofThrowable(-1, throwable);}return Result.ofSuccess(entity);}PutMapping(/rule/{id})AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultFlowRuleEntity apiUpdateFlowRule(PathVariable(id) Long id,RequestBody FlowRuleEntity entity) {if (id null || id 0) {return Result.ofFail(-1, Invalid id);}FlowRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofFail(-1, id id does not exist);}if (entity null) {return Result.ofFail(-1, invalid body);}entity.setApp(oldEntity.getApp());entity.setIp(oldEntity.getIp());entity.setPort(oldEntity.getPort());ResultFlowRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}entity.setId(id);Date date new Date();entity.setGmtCreate(oldEntity.getGmtCreate());entity.setGmtModified(date);try {entity repository.save(entity);if (entity null) {return Result.ofFail(-1, save entity fail);}publishRules(oldEntity.getApp());} catch (Throwable throwable) {logger.error(Failed to update flow rule, throwable);return Result.ofThrowable(-1, throwable);}return Result.ofSuccess(entity);}DeleteMapping(/rule/{id})AuthAction(PrivilegeType.DELETE_RULE)public ResultLong apiDeleteRule(PathVariable(id) Long id) {if (id null || id 0) {return Result.ofFail(-1, Invalid id);}FlowRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);publishRules(oldEntity.getApp());} catch (Exception e) {return Result.ofFail(-1, e.getMessage());}return Result.ofSuccess(id);}private void publishRules(/*NonNull*/ String app) throws Exception {ListFlowRuleEntity rules repository.findAllByApp(app);rulePublisher.publish(app, rules);//发布后暂定一会防止立即查询 仍然是旧数据TimeUnit.MILLISECONDS.sleep(500);} } 5.4. GatewayApiController 修改 com.alibaba.csp.sentinel.dashboard.controller.gateway包下的GatewayApiController内容如下 package com.alibaba.csp.sentinel.dashboard.controller.gateway;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.datasource.entity.gateway.ApiDefinitionEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiPredicateItemEntity; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; import com.alibaba.csp.sentinel.dashboard.domain.Result; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.AddApiReqVo; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.ApiPredicateItemVo; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api.UpdateApiReqVo; import com.alibaba.csp.sentinel.dashboard.repository.gateway.InMemApiDefinitionStore; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.util.StringUtil; 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.util.CollectionUtils; import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest; import java.util.*;import static com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants.*;/*** Gateway api Controller for manage gateway api definitions.** author cdfive* since 1.7.0*/ RestController RequestMapping(value /gateway/api) public class GatewayApiController {private final Logger logger LoggerFactory.getLogger(GatewayApiController.class);Autowiredprivate InMemApiDefinitionStore repository;// Autowired // private SentinelApiClient sentinelApiClient;AutowiredQualifier(gatewayApiRuleNacosProvider)private DynamicRuleProviderListApiDefinitionEntity provider;AutowiredQualifier(gatewayApiRuleNacosPublisher)private DynamicRulePublisherListApiDefinitionEntity publisher;GetMapping(/list.json)AuthAction(AuthService.PrivilegeType.READ_RULE)public ResultListApiDefinitionEntity queryApis(String app, String ip, Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cant be null or empty);}if (port null) {return Result.ofFail(-1, port cant be null);}try { // ListApiDefinitionEntity apis sentinelApiClient.fetchApis(app, ip, port).get();ListApiDefinitionEntity apis provider.getRules(app);repository.saveAll(apis);return Result.ofSuccess(apis);} catch (Throwable throwable) {logger.error(queryApis error:, throwable);return Result.ofThrowable(-1, throwable);}}PostMapping(/new.json)AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultApiDefinitionEntity addApi(HttpServletRequest request, RequestBody AddApiReqVo reqVo) {String app reqVo.getApp();if (StringUtil.isBlank(app)) {return Result.ofFail(-1, app cant be null or empty);}ApiDefinitionEntity entity new ApiDefinitionEntity();entity.setApp(app.trim());String ip reqVo.getIp();if (StringUtil.isBlank(ip)) {return Result.ofFail(-1, ip cant be null or empty);}entity.setIp(ip.trim());Integer port reqVo.getPort();if (port null) {return Result.ofFail(-1, port cant be null);}entity.setPort(port);// API名称String apiName reqVo.getApiName();if (StringUtil.isBlank(apiName)) {return Result.ofFail(-1, apiName cant be null or empty);}entity.setApiName(apiName.trim());// 匹配规则列表ListApiPredicateItemVo predicateItems reqVo.getPredicateItems();if (CollectionUtils.isEmpty(predicateItems)) {return Result.ofFail(-1, predicateItems cant empty);}ListApiPredicateItemEntity predicateItemEntities new ArrayList();for (ApiPredicateItemVo predicateItem : predicateItems) {ApiPredicateItemEntity predicateItemEntity new ApiPredicateItemEntity();// 匹配模式Integer matchStrategy predicateItem.getMatchStrategy();if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {return Result.ofFail(-1, invalid matchStrategy: matchStrategy);}predicateItemEntity.setMatchStrategy(matchStrategy);// 匹配串String pattern predicateItem.getPattern();if (StringUtil.isBlank(pattern)) {return Result.ofFail(-1, pattern cant be null or empty);}predicateItemEntity.setPattern(pattern);predicateItemEntities.add(predicateItemEntity);}entity.setPredicateItems(new LinkedHashSet(predicateItemEntities));// 检查API名称不能重复ListApiDefinitionEntity allApis repository.findAllByMachine(MachineInfo.of(app.trim(), ip.trim(), port));if (allApis.stream().map(o - o.getApiName()).anyMatch(o - o.equals(apiName.trim()))) {return Result.ofFail(-1, apiName exists: apiName);}Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(add gateway api error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishApis(app, ip, port)) {logger.warn(publish gateway apis fail after add);}return Result.ofSuccess(entity);}PostMapping(/save.json)AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultApiDefinitionEntity updateApi(RequestBody UpdateApiReqVo reqVo) {String app reqVo.getApp();if (StringUtil.isBlank(app)) {return Result.ofFail(-1, app cant be null or empty);}Long id reqVo.getId();if (id null) {return Result.ofFail(-1, id cant be null);}ApiDefinitionEntity entity repository.findById(id);if (entity null) {return Result.ofFail(-1, api does not exist, id id);}// 匹配规则列表ListApiPredicateItemVo predicateItems reqVo.getPredicateItems();if (CollectionUtils.isEmpty(predicateItems)) {return Result.ofFail(-1, predicateItems cant empty);}ListApiPredicateItemEntity predicateItemEntities new ArrayList();for (ApiPredicateItemVo predicateItem : predicateItems) {ApiPredicateItemEntity predicateItemEntity new ApiPredicateItemEntity();// 匹配模式int matchStrategy predicateItem.getMatchStrategy();if (!Arrays.asList(URL_MATCH_STRATEGY_EXACT, URL_MATCH_STRATEGY_PREFIX, URL_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {return Result.ofFail(-1, Invalid matchStrategy: matchStrategy);}predicateItemEntity.setMatchStrategy(matchStrategy);// 匹配串String pattern predicateItem.getPattern();if (StringUtil.isBlank(pattern)) {return Result.ofFail(-1, pattern cant be null or empty);}predicateItemEntity.setPattern(pattern);predicateItemEntities.add(predicateItemEntity);}entity.setPredicateItems(new LinkedHashSet(predicateItemEntities));Date date new Date();entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(update gateway api error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishApis(app, entity.getIp(), entity.getPort())) {logger.warn(publish gateway apis fail after update);}return Result.ofSuccess(entity);}PostMapping(/delete.json)AuthAction(AuthService.PrivilegeType.DELETE_RULE)public ResultLong deleteApi(Long id) {if (id null) {return Result.ofFail(-1, id cant be null);}ApiDefinitionEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);} catch (Throwable throwable) {logger.error(delete gateway api error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishApis(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.warn(publish gateway apis fail after delete);}return Result.ofSuccess(id);}private boolean publishApis(String app, String ip, Integer port) {ListApiDefinitionEntity apis repository.findAllByMachine(MachineInfo.of(app, ip, port));try {publisher.publish(app, apis);return true;} catch (Exception e) {e.printStackTrace();return false;}} } 5.5. GatewayFlowRuleController 修改 com.alibaba.csp.sentinel.dashboard.controller.gateway包下的GatewayFlowRuleController内容如下 package com.alibaba.csp.sentinel.dashboard.controller.gateway;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.datasource.entity.gateway.GatewayFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayParamFlowItemEntity; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; import com.alibaba.csp.sentinel.dashboard.domain.Result; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.AddFlowRuleReqVo; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.GatewayParamFlowItemVo; import com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.rule.UpdateFlowRuleReqVo; import com.alibaba.csp.sentinel.dashboard.repository.gateway.InMemGatewayFlowRuleStore; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider; import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher; import com.alibaba.csp.sentinel.util.StringUtil; 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.*;import java.util.Arrays; import java.util.Date; import java.util.List;import static com.alibaba.csp.sentinel.slots.block.RuleConstant.*; import static com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants.*; import static com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity.*;/*** Gateway flow rule Controller for manage gateway flow rules.** author cdfive* since 1.7.0*/ RestController RequestMapping(value /gateway/flow) public class GatewayFlowRuleController {private final Logger logger LoggerFactory.getLogger(GatewayFlowRuleController.class);Autowiredprivate InMemGatewayFlowRuleStore repository; // // Autowired // private SentinelApiClient sentinelApiClient;AutowiredQualifier(gatewayFlowRuleNacosProvider)private DynamicRuleProviderListGatewayFlowRuleEntity provider;AutowiredQualifier(gatewayFlowRuleNacosPublisher)private DynamicRulePublisherListGatewayFlowRuleEntity publisher;GetMapping(/list.json)AuthAction(AuthService.PrivilegeType.READ_RULE)public ResultListGatewayFlowRuleEntity queryFlowRules(String app, String ip, Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cant be null or empty);}if (port null) {return Result.ofFail(-1, port cant be null);}try { // ListGatewayFlowRuleEntity rules sentinelApiClient.fetchGatewayFlowRules(app, ip, port).get();ListGatewayFlowRuleEntity rules provider.getRules(app);repository.saveAll(rules);return Result.ofSuccess(rules);} catch (Throwable throwable) {logger.error(query gateway flow rules error:, throwable);return Result.ofThrowable(-1, throwable);}}PostMapping(/new.json)AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultGatewayFlowRuleEntity addFlowRule(RequestBody AddFlowRuleReqVo reqVo) {String app reqVo.getApp();if (StringUtil.isBlank(app)) {return Result.ofFail(-1, app cant be null or empty);}GatewayFlowRuleEntity entity new GatewayFlowRuleEntity();entity.setApp(app.trim());String ip reqVo.getIp();if (StringUtil.isBlank(ip)) {return Result.ofFail(-1, ip cant be null or empty);}entity.setIp(ip.trim());Integer port reqVo.getPort();if (port null) {return Result.ofFail(-1, port cant be null);}entity.setPort(port);// API类型, Route ID或API分组Integer resourceMode reqVo.getResourceMode();if (resourceMode null) {return Result.ofFail(-1, resourceMode cant be null);}if (!Arrays.asList(RESOURCE_MODE_ROUTE_ID, RESOURCE_MODE_CUSTOM_API_NAME).contains(resourceMode)) {return Result.ofFail(-1, invalid resourceMode: resourceMode);}entity.setResourceMode(resourceMode);// API名称String resource reqVo.getResource();if (StringUtil.isBlank(resource)) {return Result.ofFail(-1, resource cant be null or empty);}entity.setResource(resource.trim());// 针对请求属性GatewayParamFlowItemVo paramItem reqVo.getParamItem();if (paramItem ! null) {GatewayParamFlowItemEntity itemEntity new GatewayParamFlowItemEntity();entity.setParamItem(itemEntity);// 参数属性 0-ClientIP 1-Remote Host 2-Header 3-URL参数 4-CookieInteger parseStrategy paramItem.getParseStrategy();if (!Arrays.asList(PARAM_PARSE_STRATEGY_CLIENT_IP, PARAM_PARSE_STRATEGY_HOST, PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {return Result.ofFail(-1, invalid parseStrategy: parseStrategy);}itemEntity.setParseStrategy(paramItem.getParseStrategy());// 当参数属性为2-Header 3-URL参数 4-Cookie时参数名称必填if (Arrays.asList(PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {// 参数名称String fieldName paramItem.getFieldName();if (StringUtil.isBlank(fieldName)) {return Result.ofFail(-1, fieldName cant be null or empty);}itemEntity.setFieldName(paramItem.getFieldName());}String pattern paramItem.getPattern();// 如果匹配串不为空验证匹配模式if (StringUtil.isNotEmpty(pattern)) {itemEntity.setPattern(pattern);Integer matchStrategy paramItem.getMatchStrategy();if (!Arrays.asList(PARAM_MATCH_STRATEGY_EXACT, PARAM_MATCH_STRATEGY_CONTAINS, PARAM_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {return Result.ofFail(-1, invalid matchStrategy: matchStrategy);}itemEntity.setMatchStrategy(matchStrategy);}}// 阈值类型 0-线程数 1-QPSInteger grade reqVo.getGrade();if (grade null) {return Result.ofFail(-1, grade cant be null);}if (!Arrays.asList(FLOW_GRADE_THREAD, FLOW_GRADE_QPS).contains(grade)) {return Result.ofFail(-1, invalid grade: grade);}entity.setGrade(grade);// QPS阈值Double count reqVo.getCount();if (count null) {return Result.ofFail(-1, count cant be null);}if (count 0) {return Result.ofFail(-1, count should be at lease zero);}entity.setCount(count);// 间隔Long interval reqVo.getInterval();if (interval null) {return Result.ofFail(-1, interval cant be null);}if (interval 0) {return Result.ofFail(-1, interval should be greater than zero);}entity.setInterval(interval);// 间隔单位Integer intervalUnit reqVo.getIntervalUnit();if (intervalUnit null) {return Result.ofFail(-1, intervalUnit cant be null);}if (!Arrays.asList(INTERVAL_UNIT_SECOND, INTERVAL_UNIT_MINUTE, INTERVAL_UNIT_HOUR, INTERVAL_UNIT_DAY).contains(intervalUnit)) {return Result.ofFail(-1, Invalid intervalUnit: intervalUnit);}entity.setIntervalUnit(intervalUnit);// 流控方式 0-快速失败 2-匀速排队Integer controlBehavior reqVo.getControlBehavior();if (controlBehavior null) {return Result.ofFail(-1, controlBehavior cant be null);}if (!Arrays.asList(CONTROL_BEHAVIOR_DEFAULT, CONTROL_BEHAVIOR_RATE_LIMITER).contains(controlBehavior)) {return Result.ofFail(-1, invalid controlBehavior: controlBehavior);}entity.setControlBehavior(controlBehavior);if (CONTROL_BEHAVIOR_DEFAULT controlBehavior) {// 0-快速失败, 则Burst size必填Integer burst reqVo.getBurst();if (burst null) {return Result.ofFail(-1, burst cant be null);}if (burst 0) {return Result.ofFail(-1, invalid burst: burst);}entity.setBurst(burst);} else if (CONTROL_BEHAVIOR_RATE_LIMITER controlBehavior) {// 1-匀速排队, 则超时时间必填Integer maxQueueingTimeoutMs reqVo.getMaxQueueingTimeoutMs();if (maxQueueingTimeoutMs null) {return Result.ofFail(-1, maxQueueingTimeoutMs cant be null);}if (maxQueueingTimeoutMs 0) {return Result.ofFail(-1, invalid maxQueueingTimeoutMs: maxQueueingTimeoutMs);}entity.setMaxQueueingTimeoutMs(maxQueueingTimeoutMs);}Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(add gateway flow rule error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(app, ip, port)) {logger.warn(publish gateway flow rules fail after add);}return Result.ofSuccess(entity);}PostMapping(/save.json)AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultGatewayFlowRuleEntity updateFlowRule(RequestBody UpdateFlowRuleReqVo reqVo) {String app reqVo.getApp();if (StringUtil.isBlank(app)) {return Result.ofFail(-1, app cant be null or empty);}Long id reqVo.getId();if (id null) {return Result.ofFail(-1, id cant be null);}GatewayFlowRuleEntity entity repository.findById(id);if (entity null) {return Result.ofFail(-1, gateway flow rule does not exist, id id);}// 针对请求属性GatewayParamFlowItemVo paramItem reqVo.getParamItem();if (paramItem ! null) {GatewayParamFlowItemEntity itemEntity new GatewayParamFlowItemEntity();entity.setParamItem(itemEntity);// 参数属性 0-ClientIP 1-Remote Host 2-Header 3-URL参数 4-CookieInteger parseStrategy paramItem.getParseStrategy();if (!Arrays.asList(PARAM_PARSE_STRATEGY_CLIENT_IP, PARAM_PARSE_STRATEGY_HOST, PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {return Result.ofFail(-1, invalid parseStrategy: parseStrategy);}itemEntity.setParseStrategy(paramItem.getParseStrategy());// 当参数属性为2-Header 3-URL参数 4-Cookie时参数名称必填if (Arrays.asList(PARAM_PARSE_STRATEGY_HEADER, PARAM_PARSE_STRATEGY_URL_PARAM, PARAM_PARSE_STRATEGY_COOKIE).contains(parseStrategy)) {// 参数名称String fieldName paramItem.getFieldName();if (StringUtil.isBlank(fieldName)) {return Result.ofFail(-1, fieldName cant be null or empty);}itemEntity.setFieldName(paramItem.getFieldName());}String pattern paramItem.getPattern();// 如果匹配串不为空验证匹配模式if (StringUtil.isNotEmpty(pattern)) {itemEntity.setPattern(pattern);Integer matchStrategy paramItem.getMatchStrategy();if (!Arrays.asList(PARAM_MATCH_STRATEGY_EXACT, PARAM_MATCH_STRATEGY_CONTAINS, PARAM_MATCH_STRATEGY_REGEX).contains(matchStrategy)) {return Result.ofFail(-1, invalid matchStrategy: matchStrategy);}itemEntity.setMatchStrategy(matchStrategy);}} else {entity.setParamItem(null);}// 阈值类型 0-线程数 1-QPSInteger grade reqVo.getGrade();if (grade null) {return Result.ofFail(-1, grade cant be null);}if (!Arrays.asList(FLOW_GRADE_THREAD, FLOW_GRADE_QPS).contains(grade)) {return Result.ofFail(-1, invalid grade: grade);}entity.setGrade(grade);// QPS阈值Double count reqVo.getCount();if (count null) {return Result.ofFail(-1, count cant be null);}if (count 0) {return Result.ofFail(-1, count should be at lease zero);}entity.setCount(count);// 间隔Long interval reqVo.getInterval();if (interval null) {return Result.ofFail(-1, interval cant be null);}if (interval 0) {return Result.ofFail(-1, interval should be greater than zero);}entity.setInterval(interval);// 间隔单位Integer intervalUnit reqVo.getIntervalUnit();if (intervalUnit null) {return Result.ofFail(-1, intervalUnit cant be null);}if (!Arrays.asList(INTERVAL_UNIT_SECOND, INTERVAL_UNIT_MINUTE, INTERVAL_UNIT_HOUR, INTERVAL_UNIT_DAY).contains(intervalUnit)) {return Result.ofFail(-1, Invalid intervalUnit: intervalUnit);}entity.setIntervalUnit(intervalUnit);// 流控方式 0-快速失败 2-匀速排队Integer controlBehavior reqVo.getControlBehavior();if (controlBehavior null) {return Result.ofFail(-1, controlBehavior cant be null);}if (!Arrays.asList(CONTROL_BEHAVIOR_DEFAULT, CONTROL_BEHAVIOR_RATE_LIMITER).contains(controlBehavior)) {return Result.ofFail(-1, invalid controlBehavior: controlBehavior);}entity.setControlBehavior(controlBehavior);if (CONTROL_BEHAVIOR_DEFAULT controlBehavior) {// 0-快速失败, 则Burst size必填Integer burst reqVo.getBurst();if (burst null) {return Result.ofFail(-1, burst cant be null);}if (burst 0) {return Result.ofFail(-1, invalid burst: burst);}entity.setBurst(burst);} else if (CONTROL_BEHAVIOR_RATE_LIMITER controlBehavior) {// 2-匀速排队, 则超时时间必填Integer maxQueueingTimeoutMs reqVo.getMaxQueueingTimeoutMs();if (maxQueueingTimeoutMs null) {return Result.ofFail(-1, maxQueueingTimeoutMs cant be null);}if (maxQueueingTimeoutMs 0) {return Result.ofFail(-1, invalid maxQueueingTimeoutMs: maxQueueingTimeoutMs);}entity.setMaxQueueingTimeoutMs(maxQueueingTimeoutMs);}Date date new Date();entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(update gateway flow rule error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(app, entity.getIp(), entity.getPort())) {logger.warn(publish gateway flow rules fail after update);}return Result.ofSuccess(entity);}PostMapping(/delete.json)AuthAction(AuthService.PrivilegeType.DELETE_RULE)public ResultLong deleteFlowRule(Long id) {if (id null) {return Result.ofFail(-1, id cant be null);}GatewayFlowRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);} catch (Throwable throwable) {logger.error(delete gateway flow rule error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.warn(publish gateway flow rules fail after delete);}return Result.ofSuccess(id);}private boolean publishRules(String app, String ip, Integer port) {ListGatewayFlowRuleEntity rules repository.findAllByMachine(MachineInfo.of(app, ip, port));try {publisher.publish(app, rules);return true;} catch (Exception e) {e.printStackTrace();return false;}} } 5.6. ParamFlowRuleController 修改 com.alibaba.csp.sentinel.dashboard.controller包下的ParamFlowRuleController内容如下 package com.alibaba.csp.sentinel.dashboard.controller;import com.alibaba.csp.sentinel.dashboard.auth.AuthAction; import com.alibaba.csp.sentinel.dashboard.auth.AuthService; import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType; import com.alibaba.csp.sentinel.dashboard.client.CommandNotFoundException; import com.alibaba.csp.sentinel.dashboard.datasource.entity.SentinelVersion; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; import com.alibaba.csp.sentinel.dashboard.domain.Result; 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.dashboard.util.VersionUtils; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.util.StringUtil; 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.*;import java.util.Date; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException;/*** author Eric Zhao* since 0.2.1*/ RestController RequestMapping(value /paramFlow) public class ParamFlowRuleController {private final Logger logger LoggerFactory.getLogger(ParamFlowRuleController.class);// Autowired // private SentinelApiClient sentinelApiClient;Autowiredprivate AppManagement appManagement;Autowiredprivate RuleRepositoryParamFlowRuleEntity, Long repository;AutowiredQualifier(paramRuleNacosProvider)private DynamicRuleProviderListParamFlowRuleEntity ruleProvider;AutowiredQualifier(paramRuleNacosPublisher)private DynamicRulePublisherListParamFlowRuleEntity rulePublisher;private boolean checkIfSupported(String app, String ip, int port) {try {return Optional.ofNullable(appManagement.getDetailApp(app)).flatMap(e - e.getMachine(ip, port)).flatMap(m - VersionUtils.parseVersion(m.getVersion()).map(v - v.greaterOrEqual(version020))).orElse(true);// If error occurred or cannot retrieve machine info, return true.} catch (Exception ex) {return true;}}GetMapping(/rules)AuthAction(PrivilegeType.READ_RULE)public ResultListParamFlowRuleEntity apiQueryAllRulesForMachine(RequestParam String app,RequestParam String ip,RequestParam Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cannot be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cannot be null or empty);}if (port null || port 0) {return Result.ofFail(-1, Invalid parameter: port);}if (!checkIfSupported(app, ip, port)) {return unsupportedVersion();}try { // return sentinelApiClient.fetchParamFlowRulesOfMachine(app, ip, port) // .thenApply(repository::saveAll) // .thenApply(Result::ofSuccess) // .get();ListParamFlowRuleEntity rules ruleProvider.getRules(app);repository.saveAll(rules);return Result.ofSuccess(rules);} catch (ExecutionException ex) {logger.error(Error when querying parameter flow rules, ex.getCause());if (isNotSupported(ex.getCause())) {return unsupportedVersion();} else {return Result.ofThrowable(-1, ex.getCause());}} catch (Throwable throwable) {logger.error(Error when querying parameter flow rules, throwable);return Result.ofFail(-1, throwable.getMessage());}}private boolean isNotSupported(Throwable ex) {return ex instanceof CommandNotFoundException;}PostMapping(/rule)AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultParamFlowRuleEntity apiAddParamFlowRule(RequestBody ParamFlowRuleEntity entity) {ResultParamFlowRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}if (!checkIfSupported(entity.getApp(), entity.getIp(), entity.getPort())) {return unsupportedVersion();}entity.setId(null);entity.getRule().setResource(entity.getResource().trim());Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);publishRules(entity.getApp(), entity.getIp(), entity.getPort());return Result.ofSuccess(entity);} catch (ExecutionException ex) {logger.error(Error when adding new parameter flow rules, ex.getCause());if (isNotSupported(ex.getCause())) {return unsupportedVersion();} else {return Result.ofThrowable(-1, ex.getCause());}} catch (Throwable throwable) {logger.error(Error when adding new parameter flow rules, throwable);return Result.ofFail(-1, throwable.getMessage());}}private R ResultR checkEntityInternal(ParamFlowRuleEntity entity) {if (entity null) {return Result.ofFail(-1, bad rule body);}if (StringUtil.isBlank(entity.getApp())) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isBlank(entity.getIp())) {return Result.ofFail(-1, ip cant be null or empty);}if (entity.getPort() null || entity.getPort() 0) {return Result.ofFail(-1, port cant be null);}if (entity.getRule() null) {return Result.ofFail(-1, rule cant be null);}if (StringUtil.isBlank(entity.getResource())) {return Result.ofFail(-1, resource name cannot be null or empty);}if (entity.getCount() 0) {return Result.ofFail(-1, count should be valid);}if (entity.getGrade() ! RuleConstant.FLOW_GRADE_QPS) {return Result.ofFail(-1, Unknown mode (blockGrade) for parameter flow control);}if (entity.getParamIdx() null || entity.getParamIdx() 0) {return Result.ofFail(-1, paramIdx should be valid);}if (entity.getDurationInSec() 0) {return Result.ofFail(-1, durationInSec should be valid);}if (entity.getControlBehavior() 0) {return Result.ofFail(-1, controlBehavior should be valid);}return null;}PutMapping(/rule/{id})AuthAction(AuthService.PrivilegeType.WRITE_RULE)public ResultParamFlowRuleEntity apiUpdateParamFlowRule(PathVariable(id) Long id,RequestBody ParamFlowRuleEntity entity) {if (id null || id 0) {return Result.ofFail(-1, Invalid id);}ParamFlowRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofFail(-1, id id does not exist);}ResultParamFlowRuleEntity checkResult checkEntityInternal(entity);if (checkResult ! null) {return checkResult;}if (!checkIfSupported(entity.getApp(), entity.getIp(), entity.getPort())) {return unsupportedVersion();}entity.setId(id);Date date new Date();entity.setGmtCreate(oldEntity.getGmtCreate());entity.setGmtModified(date);try {entity repository.save(entity);publishRules(entity.getApp(), entity.getIp(), entity.getPort());return Result.ofSuccess(entity);} catch (ExecutionException ex) {logger.error(Error when updating parameter flow rules, id id, ex.getCause());if (isNotSupported(ex.getCause())) {return unsupportedVersion();} else {return Result.ofThrowable(-1, ex.getCause());}} catch (Throwable throwable) {logger.error(Error when updating parameter flow rules, id id, throwable);return Result.ofFail(-1, throwable.getMessage());}}DeleteMapping(/rule/{id})AuthAction(PrivilegeType.DELETE_RULE)public ResultLong apiDeleteRule(PathVariable(id) Long id) {if (id null) {return Result.ofFail(-1, id cannot be null);}ParamFlowRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort());return Result.ofSuccess(id);} catch (ExecutionException ex) {logger.error(Error when deleting parameter flow rules, ex.getCause());if (isNotSupported(ex.getCause())) {return unsupportedVersion();} else {return Result.ofThrowable(-1, ex.getCause());}} catch (Throwable throwable) {logger.error(Error when deleting parameter flow rules, throwable);return Result.ofFail(-1, throwable.getMessage());}}private void publishRules(String app, String ip, Integer port) throws Exception {ListParamFlowRuleEntity rules repository.findAllByMachine(MachineInfo.of(app, ip, port)); // return sentinelApiClient.setParamFlowRuleOfMachine(app, ip, port, rules);rulePublisher.publish(app, rules);}private R ResultR unsupportedVersion() {return Result.ofFail(4041,Sentinel client not supported for parameter flow control (unsupported version or dependency absent));}private final SentinelVersion version020 new SentinelVersion().setMinorVersion(2); } 5.7. SystemController 修改 com.alibaba.csp.sentinel.dashboard.controller包下的SystemController内容如下 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.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.util.StringUtil;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity; import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo; import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient; 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.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/*** author leyou(lihao)*/ RestController RequestMapping(/system) public class SystemController {private final Logger logger LoggerFactory.getLogger(SystemController.class);Autowiredprivate RuleRepositorySystemRuleEntity, Long repository;Autowiredprivate SentinelApiClient sentinelApiClient;AutowiredQualifier(systemRuleNacosProvider)private DynamicRuleProviderListSystemRuleEntity ruleProvider;AutowiredQualifier(systemRuleNacosPublisher)private DynamicRulePublisherListSystemRuleEntity rulePublisher;private R ResultR checkBasicParams(String app, String ip, Integer port) {if (StringUtil.isEmpty(app)) {return Result.ofFail(-1, app cant be null or empty);}if (StringUtil.isEmpty(ip)) {return Result.ofFail(-1, ip cant be null or empty);}if (port null) {return Result.ofFail(-1, port cant be null);}if (port 0 || port 65535) {return Result.ofFail(-1, port should be in (0, 65535));}return null;}GetMapping(/rules.json)AuthAction(PrivilegeType.READ_RULE)public ResultListSystemRuleEntity apiQueryMachineRules(String app, String ip,Integer port) {ResultListSystemRuleEntity checkResult checkBasicParams(app, ip, port);if (checkResult ! null) {return checkResult;}try { // ListSystemRuleEntity rules sentinelApiClient.fetchSystemRuleOfMachine(app, ip, port);ListSystemRuleEntity rules ruleProvider.getRules(app);rules repository.saveAll(rules);return Result.ofSuccess(rules);} catch (Throwable throwable) {logger.error(Query machine system rules error, throwable);return Result.ofThrowable(-1, throwable);}}private int countNotNullAndNotNegative(Number... values) {int notNullCount 0;for (int i 0; i values.length; i) {if (values[i] ! null values[i].doubleValue() 0) {notNullCount;}}return notNullCount;}RequestMapping(/new.json)AuthAction(PrivilegeType.WRITE_RULE)public ResultSystemRuleEntity apiAdd(String app, String ip, Integer port,Double highestSystemLoad, Double highestCpuUsage, Long avgRt,Long maxThread, Double qps) {ResultSystemRuleEntity checkResult checkBasicParams(app, ip, port);if (checkResult ! null) {return checkResult;}int notNullCount countNotNullAndNotNegative(highestSystemLoad, avgRt, maxThread, qps, highestCpuUsage);if (notNullCount ! 1) {return Result.ofFail(-1, only one of [highestSystemLoad, avgRt, maxThread, qps,highestCpuUsage] value must be set 0, but notNullCount values get);}if (null ! highestCpuUsage highestCpuUsage 1) {return Result.ofFail(-1, highestCpuUsage must between [0.0, 1.0]);}SystemRuleEntity entity new SystemRuleEntity();entity.setApp(app.trim());entity.setIp(ip.trim());entity.setPort(port);// -1 is a fake valueif (null ! highestSystemLoad) {entity.setHighestSystemLoad(highestSystemLoad);} else {entity.setHighestSystemLoad(-1D);}if (null ! highestCpuUsage) {entity.setHighestCpuUsage(highestCpuUsage);} else {entity.setHighestCpuUsage(-1D);}if (avgRt ! null) {entity.setAvgRt(avgRt);} else {entity.setAvgRt(-1L);}if (maxThread ! null) {entity.setMaxThread(maxThread);} else {entity.setMaxThread(-1L);}if (qps ! null) {entity.setQps(qps);} else {entity.setQps(-1D);}Date date new Date();entity.setGmtCreate(date);entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(Add SystemRule error, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(app, ip, port)) {logger.warn(Publish system rules fail after rule add);}return Result.ofSuccess(entity);}GetMapping(/save.json)AuthAction(PrivilegeType.WRITE_RULE)public ResultSystemRuleEntity apiUpdateIfNotNull(Long id, String app, Double highestSystemLoad,Double highestCpuUsage, Long avgRt, Long maxThread, Double qps) {if (id null) {return Result.ofFail(-1, id cant be null);}SystemRuleEntity entity repository.findById(id);if (entity null) {return Result.ofFail(-1, id id dose not exist);}if (StringUtil.isNotBlank(app)) {entity.setApp(app.trim());}if (highestSystemLoad ! null) {if (highestSystemLoad 0) {return Result.ofFail(-1, highestSystemLoad must 0);}entity.setHighestSystemLoad(highestSystemLoad);}if (highestCpuUsage ! null) {if (highestCpuUsage 0) {return Result.ofFail(-1, highestCpuUsage must 0);}if (highestCpuUsage 1) {return Result.ofFail(-1, highestCpuUsage must 1);}entity.setHighestCpuUsage(highestCpuUsage);}if (avgRt ! null) {if (avgRt 0) {return Result.ofFail(-1, avgRt must 0);}entity.setAvgRt(avgRt);}if (maxThread ! null) {if (maxThread 0) {return Result.ofFail(-1, maxThread must 0);}entity.setMaxThread(maxThread);}if (qps ! null) {if (qps 0) {return Result.ofFail(-1, qps must 0);}entity.setQps(qps);}Date date new Date();entity.setGmtModified(date);try {entity repository.save(entity);} catch (Throwable throwable) {logger.error(save error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.info(publish system rules fail after rule update);}return Result.ofSuccess(entity);}RequestMapping(/delete.json)AuthAction(PrivilegeType.DELETE_RULE)public Result? delete(Long id) {if (id null) {return Result.ofFail(-1, id cant be null);}SystemRuleEntity oldEntity repository.findById(id);if (oldEntity null) {return Result.ofSuccess(null);}try {repository.delete(id);} catch (Throwable throwable) {logger.error(delete error:, throwable);return Result.ofThrowable(-1, throwable);}if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.info(publish system rules fail after rule delete);}return Result.ofSuccess(id);}private boolean publishRules(String app, String ip, Integer port) {ListSystemRuleEntity rules repository.findAllByMachine(MachineInfo.of(app, ip, port)); // return sentinelApiClient.setSystemRuleOfMachine(app, ip, port, rules);try {rulePublisher.publish(app, rules);return true;} catch (Exception e) {return false;}} } 六、前端代码调整 6.1. sidebar.html 修改前端代码 找到webapp/resources/app/scripts/directives/sidebar/sidebar.html文件找到以下代码 li ui-sref-activeactive ng-if!entry.isGatewaya ui-srefdashboard.flowV1({app: entry.app})i classglyphicon glyphicon-filter/inbsp;nbsp;流控规则/a /li 修改为 !-- 修改 dashboard.flowV1 为 dashboard.flow-- li ui-sref-activeactive ng-if!entry.isGatewaya ui-srefdashboard.flow({app: entry.app})i classglyphicon glyphicon-filter/inbsp;nbsp;流控规则/a /li 6.2. flow_service_v1.js 找到webapp/resources/app/scripts/services/flow_service_v1.js文件找到以下代码 this.newRule function (rule) {var param {resource: rule.resource,limitApp: rule.limitApp,grade: rule.grade,count: rule.count,strategy: rule.strategy,refResource: rule.refResource,controlBehavior: rule.controlBehavior,warmUpPeriodSec: rule.warmUpPeriodSec,maxQueueingTimeMs: rule.maxQueueingTimeMs,app: rule.app,ip: rule.ip,port: rule.port};return $http({url: /v1/flow/rule,data: rule,method: POST}); }; 修改为 this.newRule function (rule) {var param {resource: rule.resource,limitApp: rule.limitApp,grade: rule.grade,count: rule.count,strategy: rule.strategy,refResource: rule.refResource,controlBehavior: rule.controlBehavior,warmUpPeriodSec: rule.warmUpPeriodSec,maxQueueingTimeMs: rule.maxQueueingTimeMs,app: rule.app,ip: rule.ip,port: rule.port};return $http({url: /v2/flow/rule,data: rule,method: POST}); }; 主要是将 url 里的 v1 改为 v2。 6.3. identity.js 找到webapp/resources/app/scripts/controllers/identity.js文件找到以下代码 function saveFlowRule() {if (!FlowService.checkRuleValid(flowRuleDialogScope.currentRule)) {return;}FlowService.newRule(flowRuleDialogScope.currentRule).success(function (data) {if (data.code 0) {flowRuleDialog.close();let url /dashboard/flow/ $scope.app;$location.path(url);} else {alert(失败 data.msg);}}).error((data, header, config, status) {alert(未知错误);}); } 修改为 function saveFlowRule() {if (!FlowService.checkRuleValid(flowRuleDialogScope.currentRule)) {return;}FlowService.newRule(flowRuleDialogScope.currentRule).success(function (data) {if (data.code 0) {flowRuleDialog.close();let url /dashboard/v2/flow/ $scope.app;$location.path(url);} else {alert(失败 data.msg);}}).error((data, header, config, status) {alert(未知错误);}); } 主要是将跳转到 v1 版本的流控界面改为跳转到 v2 版本的流控界面。 6.4. flow_v2.html 找到webapp/resources/app/views/flow_v2.html文件找到以下代码 a classbtn btn-default-inverse stylefloat: right; margin-right: 10px; ui-srefdashboard.flowV1({app: app})回到单机页面 /a 将其注释掉或删掉。 七、修改的文件总览 7.1. 后端文件列表 路径说sentinel-dashboard/pom.xml依赖sentinel-dashboard/src/main/resources/application.propertiescom.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig 新增部分 路径说明com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosPropertiesConfigcom.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtilcom.alibaba.csp.sentinel.dashboard.rule.nacos.auth.AuthorityRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.auth.AuthorityRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.degrade.DegradeRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.degrade.DegradeRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.flow.FlowRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.flow.FlowRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api.GatewayApiRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.api.GatewayApiRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow.GatewayFlowRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.gateway.flow.GatewayFlowRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.param.ParamRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.param.ParamRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.rule.nacos.system.SystemRuleNacosProvidercom.alibaba.csp.sentinel.dashboard.rule.nacos.system.SystemRuleNacosPublishercom.alibaba.csp.sentinel.dashboard.controller.gateway.GatewayApiControllercom.alibaba.csp.sentinel.dashboard.controller.gateway.GatewayFlowRuleController 控制层 路径说明com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2com.alibaba.csp.sentinel.dashboard.controller.AuthorityRuleControllercom.alibaba.csp.sentinel.dashboard.controller.DegradeControllercom.alibaba.csp.sentinel.dashboard.controller.ParamFlowRuleControllercom.alibaba.csp.sentinel.dashboard.controller.SystemController 7.2. 前端文件列表 路径说明webapp/resources/app/scripts/directives/sidebar/sidebar.htmlwebapp/resources/app/scripts/services/flow_service_v1.jswebapp/resources/app/scripts/controllers/identity.jswebapp/resources/app/views/flow_v2.html Alibaba Sentinel Nacos 持久化规则 至此改造基本完毕。 八、编译打包 8.1. 编译前端 进入项目 webapp/resources 目录运行 npm install8.2. 编译打包后端 进入项目 sentienl-dashboard 目录运行 mvn clean package -Dmaven.test.skiptrue如果报错则进入上级目录 sentinel 执行mvn clean package -Dmaven.test.skiptrue 后重新打包。 之后会在 target 目录下生成 sentinel-dashboard.jar 。 通过以下命令运行 java -Dserver.port8888 -Dcsp.sentinel.dashboard.serverlocalhost:8888 -Dproject.namesentinel-dashboard -jar sentinel-dashboard.jar九、测试验证 9.1. 版本选取 组件版本nacos1.4.2sentinel1.8.2 9.2. 启动nacos http://localhost:8848/nacos/ 账号/密码nacos/nacos 9.3. 启动sentinel-dashboard java -Dserver.port8888 -Dcsp.sentinel.dashboard.serverlocalhost:8888 -Dproject.namesentinel-dashboard -jar sentinel-dashboard.jarhttp://localhost:8888/ 9.4. 添加流控规则 登录nacos查看规则是否同步 9.5. 重启sentinel-dashboard 在未做改造前规则存在内存中sentinel-dashboard重启后规则失效查看改造后sentinel-dashboard重启后nacos是否将规则同步到sentinel-dashboard控制台的流控规则页面中。 重新登陆sentinel-dashboard 重启后规则仍然存在 9.6. 删除流控规则 在sentinel-dashboard控制台的流控规则中将规则删除查看nacos规则是否同步删除 流控规则是空的 登录nacos查看规则是否同步删除了 9.7. nacos删除流控规则 从 nacos删除流控规则 验证sentinel-dashboard是否同步删除其实想验证nacos修改规则参数sentinel-dashboard控制台是否同步配置。 删除前 删除规则 登录sentinel-dashboard查看规则是否还存在 刷新sentinel-dashboard 发现规则没有验证效果符合预期 从上面截图中可以看出流控规则删除了后nacos保存得流控规则也同步删除了。 9.8. nacos修改流控规则 在nacos上修改流控规则验证sentinel-dashboard控制台是否同步 修改前 修改后 登录sentinel-dashboard控制台查看流控规则配置是否也同步修改了 从截图中可以看出配置同步修改了 9.9. 测试结论 从上面通过在sentinel-dashboard控制台对流控规则的增加、删除以及sentinel-dashboard服务的重启启动nacos上规则删除、规则修改等方面测试结果可以看出符合预期说明改造sentinel-dashboard使用Nacos持久化规则成功 十、微服务集成 10.1. pom依赖引入 parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.3.2.RELEASE/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!--服务注册发现--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--配置管理--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId/dependency!--配置sentinel持久化规则到nacos--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId/dependency!--流控降级管理--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency/dependenciesdependencyManagementdependencies!--spring-cloud-alibaba依赖版本控制--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion2.2.6.RELEASE/versionscopeimport/scopetypepom/type/dependency/dependencies/dependencyManagement10.2. sentinel规则持久化配置 spring:cloud:sentinel:transport:dashboard: 127.0.0.1:8888datasource:# 名称随意flow:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-flow-rulesgroupId: SENTINEL_GROUP# 规则类型取值见# org.springframework.cloud.alibaba.sentinel.datasource.RuleTyperule-type: flowdegrade:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUPrule-type: degradesystem:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-system-rulesgroupId: SENTINEL_GROUPrule-type: systemauthority:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-authority-rulesgroupId: SENTINEL_GROUPrule-type: authorityparam-flow:nacos:server-addr: localhost:8848dataId: ${spring.application.name}-param-flow-rulesgroupId: SENTINEL_GROUPrule-type: param-flownacos:discovery:service: order-servserver-addr: localhost:8848application:name: sentinel-nacosserver:port: 9000management:endpoint:endpoints:web:exposure:include: *10.3. nacos效果图 与上面的配置一一对应
http://wiki.neutronadmin.com/news/60694/

相关文章:

  • 网站建设公司口碑排名关键词是什么意思
  • 专业建站推广服务网站建设的平台
  • 做网站用广告赚钱过时了互联网工程师
  • 国外做旅游攻略的网站wordpress 调用 编辑器
  • 焦作北京网站建设旅游网站的功能设计
  • 网页设计与网站建设作品个人做网站花多少钱
  • 深圳市公司网站建设企业清河做网站
  • 广州专业网站建设哪家好香水网站开源模板
  • 网站网页设计代码wordpress速度慢设置
  • 怎么做素材网站十二师建设局网站
  • 百度店铺网站seo优化价格
  • php网站开发前端如何申请成立公司
  • 深圳南山网站建设工作室自己做图片的网站吗
  • 领动建站科技资讯
  • 月嫂的个人简历网站模板商标自动生成免费软件
  • 怎么找到网站的空间服务商wordpress 图片失效
  • 温岭网站开发阜阳做网站的网络公司
  • 请人建设网站需要注意什么网站建设单位是什么
  • 网站不能写入php文件郑州网络
  • 外贸响应式网站建设做两个网站 之间超链接
  • 做海外市场什么网站推广亚马逊网站开发设计
  • 单页网站程序天眼查公司查询企业查询
  • 南通网站建设制作公司网店代运营合同模板
  • 泉港报名网站建设需要东莞企业网站建设开发公司
  • 最大的网站建设营销型网站建设的流程
  • 娱乐手机网站开发东莞模板建网站平台
  • 网站开发项目需求分析书护肤品网站建设策划书
  • 西宁网站搭建专业公司免费发布产品信息网站
  • 招商网站建设需要什么抖音代运营服务框架
  • 商标网站建设陕西营销型网站制作