sentinel整合apollo配置中心

上篇文章大致讲解了sentinel的部署和一些基本概念以及使用,不清楚的同学建议先学习前一篇文章
传送门:https://blog.csdn.net/qq_22624361/article/details/90258222
这篇文章主要讲解sentinel与配置中心多数据源的结合。
需要结合数据源的原因是因为sentinel默认的数据是储存在内存里的,并没有实现持久化的工程,使用过程中规则数据的丢失会引起我们的使用不便。
持久化的方法主要有两种,一种是数据化直接储存,另一种是通过与配置中心的交互来更新和储存数据。
前一种方法需要自己重写实现接口,这里就不尝试了,需要尝试的同学可以参考其他大佬的文章。
传送门:https://www.cnblogs.com/cdfive2018/p/9838577.html
因为早期部署了携程开源的apollo,所以我们这里就拿apollo来实现,后期会出关于约nacos config整合的文章。
我们可以看下关于整合多数据源的官方文档
https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel

主要有三种模式,那么这里我们主要也是用官方所推荐的push模式。
关于push模式的流程图我们借用程序员DD大神的图来给大家呈现一下
在这里插入图片描述
开启pus模式主要分两块,第一块是对sentinel控制面板的改造;第二块是客户端的改造。
我们先来说关于sentinel-dashboard的改造。改造的原因主要是实现两点:
1.sentinel界面显示我们在配置中心发布的规则。
2.sentinel修改规则后可以同步推送到配置中心

第一步,我们先从官方git库把源码给拉下来,然后根据官方文档来进行改造
https://github.com/alibaba/Sentinel/wiki/Sentinel-控制台(集群流控管理)#规则配置
我们在这里插入图片描述
我们可以看到官方已经给出了demo,然后我们进行改造。
第二步,首先我们在java包下面的com.alibaba.csp.sentinel.dashboard.rule创建一个apollo包,然后创建三个类ApolloConfig,FlowRuleApolloProvider,FlowRuleApolloPublisher
然后我们来改造ApolloConfig

@Configuration
public class ApolloConfig {

    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
        return JSON::toJSONString;
    }

    @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
        return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }

    @Bean
    public ApolloOpenApiClient apolloOpenApiClient() {
        ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
            .withPortalUrl("http://localhost:10034")   // TODO 根据实际情况修改(portal_address)
            .withToken("token")  // TODO apollo开发api的token
            .build();
        return client;

    }
}

.withPortalUrl里面配置的是apollo的portal服务的地址,这里如果填错是会报openAPI 404;
.withToken 里面配置的apollo的openAPI的token;
如果不了解怎么配置openAPI的同学可以参考这篇文章
https://www.jianshu.com/p/6e243bfa9ed2
至此,ApolloConfig配置结束。

第三步,改造FlowRuleApolloProvider和FlowRuleApolloPublisher
这里的两类主要是负责sentinel向配置中心推送规则以及向配置中心拉取已经发布的规则。
先来看FlowRuleApolloProvider:

@Component("flowRuleApolloProvider")
public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {

    @Autowired
    private ApolloOpenApiClient apolloOpenApiClient;
    @Autowired
    private Converter<String, List<FlowRuleEntity>> converter;

    @Value("${env:DEV}")
    private String env;

    @Override
    public List<FlowRuleEntity> getRules(String appName) throws Exception {
        String appId = "sentinel-server";
        // flowDataId对应
        String flowDataId = "sentinel.flowRules";
        OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appId, env, null, "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);
    }

我们主要来看这两行代码:
在这里插入图片描述
appId:这里的appId就是你在apollo里面设置的appId,如果不设置会取你在客户端配置的appName.
env:部署的环境。
clusterName:集群部署名称,如没有集群则填写"default"
namespaceName:apollo中设置的namespaceName
flowDataId:这个就是你在apollo中设置的规则keyname

然后设置FlowRuleApolloPublisher

@Component("flowRuleApolloPublisher")
public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {

    @Autowired
    private ApolloOpenApiClient apolloOpenApiClient;
    @Autowired
    private Converter<List<FlowRuleEntity>, String> converter;

    @Value("${env:DEV}")
    private String env;

    @Override
    public void publish(String app, List<FlowRuleEntity> rules) throws Exception {

        if (rules == null) {
            return;
        }

        // Increase the configuration
        String appId = "sentinel-server";
        String flowDataId = "sentinel.flowRules";
        OpenItemDTO openItemDTO = new OpenItemDTO();
        openItemDTO.setKey(flowDataId);
        openItemDTO.setValue(converter.convert(rules));
        openItemDTO.setComment("Program auto-join");
        openItemDTO.setDataChangeCreatedBy("apollo");
        apolloOpenApiClient.createOrUpdateItem(appId, "DEV", "sentinel-server", "application", openItemDTO);

        // Release configuration
        NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
        namespaceReleaseDTO.setEmergencyPublish(true);
        namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
        namespaceReleaseDTO.setReleasedBy("apollo");
        namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
        apolloOpenApiClient.publishNamespace(appId, "DEV", "sentinel-server", "application", namespaceReleaseDTO);
    }

这里的参数基本上与上面的provider保持一致,但是我们这里要设置数据创建者
在这里插入图片描述
第四步,修改pom文件,将test注释掉

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-openapi</artifactId>
    <version>1.2.0</version>
    <!--<scope>test</scope>-->
</dependency>

第五步,修改resources/app/scripts/directives/sidebar/sidebar.html文件

<li ui-sref-active="active">
    <a ui-sref="dashboard.flowV1({app: entry.app})">
        <i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则
    </a>
</li>

修改为

<li ui-sref-active="active">
    <a ui-sref="dashboard.flow({app: entry.app})">
        <i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则
    </a>
</li>

第六步,修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2,将刚才我们修改的provide和publisher注入

@Autowired
@Qualifier("flowRuleApolloProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleApolloPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

至此我们对于sentinel的dashboard的改造就完成了。
接下来的一大部分是对客户端的改造
第一步,引入依赖

  <!--alibaba sentinel dataSource pull-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-extension</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <!--流控储存在apollo-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-apollo</artifactId>
            <version>${sentinel.version}</version>
        </dependency>

第二步,配置关于apollo配置中心的信息

#apollo配置中心设置
app.id=test-server
apollo.meta=http://localhost:8080
#sentinel配置
spring.cloud.sentinel.transport.port=8081
spring.cloud.sentinel.transport.dashboard=localhost:8080
# sentinel datasource apollo
#apollo的nameSpace
spring.cloud.sentinel.datasource.ds1.apollo.namespaceName=application
##流控规则
##规则类型
spring.cloud.sentinel.datasource.ds1.apollo.rule-type=flow
##配置中心里面的key
spring.cloud.sentinel.datasource.ds1.apollo.flowRulesKey=sentinel.flowRules

参数解释:
spring.cloud.sentinel.datasource.ds1:sentinel中命名的多数据源配置规则,后面可以跟ds1,ds2…等等来适配多种数据源。
apollo.rule-type:规则类型 flow代表了限流。

我们可以看到里面还有其他规则类型。
**apollo.flowRulesKey:**配置中心里面的key。这里的key和配置中心的key已经控制面板里面改造的flowDataId都是得保持一致的。这样数据才会互通。
这样,客户端也改造完成了。
我们依次启动apollo配置中心,sentinel控制台,客户端来看下效果。
我们在apollo先设置一个规则
在这里插入图片描述
这里需要注意的是规则按json方式进行交互,如果想添加第二条流控规则,则添加json对象在数组里面即可。
然后我们请求接口之后来看控制台

规则也在控制台显示。
那么我们再来试一下推送模式,我们在sentinel修改规则

然后来看配置中心

配置中心也同步更新。

项目地址:
https://github.com/fjc440/spring-cloud-learn/tree/feature-apollo

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值