# 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