# sentinel-1.6.0 **Repository Path**: jxlgzwh/sentinel-1.6.0 ## Basic Information - **Project Name**: sentinel-1.6.0 - **Description**: Sentinel-dashboard 控制台 →apollo 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2019-05-27 - **Last Updated**: 2022-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Sentinel Dashboard中修改规则同步到Apollo存储,采用官方推荐的 push 模式 Push模式 生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等), 推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。 因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。 代码实现 下面继续说说具体的代码实现,这里参考了Sentinel Dashboard源码中关于Apollo实现的测试用例。但是由于考虑到与Spring Cloud Alibaba的结合使用,略作修改。 第一步:修改pom.xml中的Apollo OpenAPi的依赖,将test注释掉,这样才能在主程序中使用。 com.ctrip.framework.apollo apollo-openapi 1.2.0 第二步:找到resources/app/scripts/directives/sidebar/sidebar.html中的这段代码:
  •   流控规则
  • 修改为:
  •   流控规则
  • 第三步:在com.alibaba.csp.sentinel.dashboard.rule包下新建一个apollo包,用来编写针对Apollo的扩展实现。 第四步:创建Apollo的配置类,定义Apollo的portal访问地址以及第三方应用访问的授权Token(通过Apollo管理员账户登录,在“开放平台授权管理”功能中创建),具体代码如下: @Configuration public class ApolloConfig { @Bean public Converter, String> flowRuleEntityEncoder() { return JSON::toJSONString; } @Bean public Converter> flowRuleEntityDecoder() { return s -> JSON.parseArray(s, FlowRuleEntity.class); } @Bean public ApolloOpenApiClient apolloOpenApiClient() { ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder() .withPortalUrl("https://apollo.xxx.com") // TODO 根据实际情况修改 .withToken("open api token") // TODO 根据实际情况修改 .build(); return client; } } 第五步:实现Apollo的配置拉取实现。 @Component("flowRuleApolloProvider") public class FlowRuleApolloProvider implements DynamicRuleProvider> { @Autowired private ApolloOpenApiClient apolloOpenApiClient; @Autowired private Converter> converter; @Value("${env:DEV}") private String env; @Override public List getRules(String appName) throws Exception { // flowDataId对应 String flowDataId = "sentinel.flowRules"; OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appName, env, "default", "application"); String rules = openNamespaceDTO .getItems() .stream() .filter(p -> p.getKey().equals(flowDataId)) .map(OpenItemDTO::getValue) .findFirst() .orElse(""); if (StringUtil.isEmpty(rules)) { return new ArrayList<>(); } return converter.convert(rules); } } getRules方法中的appName参数是Sentinel中的服务名称,这里直接通过这个名字获取Apollo配置是由于Apollo中的项目AppId与之一致,如果存在不一致的情况,则需要自己做转换。 这里注入了一个env属性,主要由于我们在使用Apollo的时候,通过启动参数来控制不同环境。所以这样就能在不同环境区分不同的限流配置了。 这里的flowDataId对应各个微服务应用中定义的spring.cloud.sentinel.datasource.ds.apollo.flowRulesKey配置,即:Apollo中使用了什么key来存储限流配置。 其他如Cluster、Namepsace都采用了默认值:default和application,这个读者有特殊需求可以做对应的修改。 第六步:实现Apollo的配置推送实现。 @Component("flowRuleApolloPublisher") public class FlowRuleApolloPublisher implements DynamicRulePublisher> { @Autowired private ApolloOpenApiClient apolloOpenApiClient; @Autowired private Converter, String> converter; @Value("${env:DEV}") private String env; @Override public void publish(String app, List rules) throws Exception { String flowDataId = "sentinel.flowRules"; AssertUtil.notEmpty(app, "app name cannot be empty"); if (rules == null) { return; } OpenItemDTO openItemDTO = new OpenItemDTO(); openItemDTO.setKey(flowDataId); openItemDTO.setValue(converter.convert(rules)); openItemDTO.setComment("modify by sentinel-dashboard"); openItemDTO.setDataChangeCreatedBy("apollo"); apolloOpenApiClient.createOrUpdateItem(app, env, "default", "application", openItemDTO); // Release configuration NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO(); namespaceReleaseDTO.setEmergencyPublish(true); namespaceReleaseDTO.setReleaseComment("release by sentinel-dashboard"); namespaceReleaseDTO.setReleasedBy("apollo"); namespaceReleaseDTO.setReleaseTitle("release by sentinel-dashboard"); apolloOpenApiClient.publishNamespace(app, env, "default", "application", namespaceReleaseDTO); } } 这里的大部分内容,如:env、flowDataId、app说明与上一步中的实现一致 openItemDTO.setDataChangeCreatedBy("apollo");和namespaceReleaseDTO.setReleasedBy("apollo");这两句需要注意一下,必须设置存在并且有权限的用户,不然会更新失败。 第七步:修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2中DynamicRuleProvider和DynamicRulePublisher注入的Bean,改为上面我们编写的针对Apollo的实现: @Autowired @Qualifier("flowRuleApolloProvider") private DynamicRuleProvider> ruleProvider; @Autowired @Qualifier("flowRuleApolloPublisher") private DynamicRulePublisher> rulePublisher; 代码示例 本文介绍内容的客户端代码,示例读者可以通过查看下面仓库中的alibaba-sentinel-dashboard-apollo项目: https://user-images.githubusercontent.com/9434884/53381986-a0b73f00-39ad-11e9-90cf-b49158ae4b6f.png 参考链接: https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel https://segmentfault.com/a/1190000019094867