Spring Cloud gateway 六 Sentinel nacos存储动态刷新

微服务当前这么火爆的程度,如果不能学会一种微服务框架技术。怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习。说没有时间?没有精力?要学俩个框架?而Spring Cloud alibaba只需要你学会一个就会拥有俩种微服务治理框架技术。何乐而不为呢?加油吧!骚猿年

### Sentinel规则

Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:

通过 API 直接修改 (loadRules)
通过 DataSource 适配不同数据源修改
手动通过 API 修改比较直观,可以通过以下几个 API 修改不同的规则:

FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则

特别注意一下这俩个方法。后面会拿一个做案例说明

手动修改规则(硬编码方式)一般仅用于测试和演示,生产上一般通过动态规则源的方式来动态管理规则。

### DataSource 扩展

上述 loadRules() 方法只接受内存态的规则对象,但更多时候规则存储在文件、数据库或者配置中心当中。DataSource 接口给我们提供了对接任意配置源的能力。相比直接通过 API 修改规则,实现 DataSource 接口是更加可靠的做法。

推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更,流程如下:

file

DataSource 扩展常见的实现方式有:

  • 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;
  • 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

Sentinel 目前支持以下数据源扩展:

  • Pull-based: 文件、Consul (since 1.7.0)
  • Push-based: ZooKeeper, Redis, Nacos, Apollo

因为是注册中心和配置中心 都使用的nacos。这里也只介绍nacos 的使用方式。

整合代码修改pom 引入jar

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改yml 配置文件。添加DataSource支持

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8890
        port: 8719
      eager: true
      datasource:
        na:
          nacos:
            server-addr: 47.99.209.72:8848
            groupId: DEFAULT_GROUP
            dataId: ${spring.application.name}-${spring.profiles.active}-sentinel
            rule-type: flow

nacos配置中心创建文件 cloud-gateway-demo-dev-sentinel
file

[
    {
        "resource": "/api",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

启动服务

查看启动台sentinel

file

如果需要动态修改。直接修改nacos对应配置文件。在进行发布,Sentinel 就会随着动态更新
这个就不带大家去做这个实验了。

还有一种情况 就是上面提高的 手动api方式修改。官方并不推荐

FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则

这种方案这里也实现一下

很简单只要增加一个ApplicationRunner 实现类就可以完成

package com.xian.cloud.runner;

import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * <Description>
 *
 * @author xianliru@163.com
 * @version 1.0
 * @createDate 2019/11/12 11:18
 */
@Component
@Slf4j
public class FlowRuleRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        try {
            List<FlowRule> rules = FlowRuleManager.getRules();
            if(rules == null ){
                rules = new ArrayList<>();
            }
            FlowRule flowRule = new FlowRule("/refreshRoutes");
            flowRule.setCount(5).setClusterMode(false).setControlBehavior(0);
            flowRule.setLimitApp("default");
            rules.add(flowRule);
            log.info("FlowRuleRunner loadRules reules:{}  ",rules);
            FlowRuleManager.loadRules(rules);
        }catch (Exception e){
            log.error("FlowRuleRunner 加载异常 :{}",e.getMessage());
        }
    }
}

这里需要要注意下ApplicationRunner 是在项目启动完成之后做的一些事情。如果在run方法里面抛出异常。不进行捕获,会导致程序直接退出

我们重启启动程序。看一下

file

思考一下,如果在配置中心修改规则以后refreshRoutes 这个限流规则还会存在么?

现在实验一下,将nacos api修改为test 并发布。

程序日志

2019-11-13 10:23:07.426  INFO 43912 --- [.99.209.72_8848] c.a.n.client.config.impl.ClientWorker    : [fixed-47.99.209.72_8848] [polling-resp] config changed. dataId=cloud-gateway-demo-dev-sentinel, group=DEFAULT_GROUP
2019-11-13 10:23:07.535  INFO 43912 --- [.99.209.72_8848] c.a.n.client.config.impl.ClientWorker    : [fixed-47.99.209.72_8848] [data-received] dataId=cloud-gateway-demo-dev-sentinel, group=DEFAULT_GROUP, tenant=null, md5=b03e221f14293f3274788cbdb24a44b4, content=[
    {
        "resource": "/test",
        "limitApp": "default",
        "grade": 1,
        "cou...
2019-11-13 10:23:07.535  INFO 43912 --- [.99.209.72_8848] c.a.nacos.client.config.impl.CacheData   : [fixed-47.99.209.72_8848] [notify-listener] time cost=0ms in ClientWorker, dataId=cloud-gateway-demo-dev-sentinel, group=DEFAULT_GROUP, md5=b03e221f14293f3274788cbdb24a44b4, listener=com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource$1@10b4e985 
2019-11-13 10:23:07.538  INFO 43912 --- [update-thread-1] c.a.nacos.client.config.impl.CacheData   : [fixed-47.99.209.72_8848] [notify-ok] dataId=cloud-gateway-demo-dev-sentinel, group=DEFAULT_GROUP, md5=b03e221f14293f3274788cbdb24a44b4, listener=com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource$1@10b4e985 

来看一下 Sentinel控制台
file

在之前通过ApplicationRunner 注入的规则消失了。

反思

  • 如果程序上选中DataSource方式存储动态的限流规则等。就不能在使用官方提供各种工具类加载规则xxx.loadRules。因为动态刷新一次,存储在内存里面的规则就会清空。

  • 手动API 方式 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境

往期资料、参考资料

Sentinel 官方文档地址

摘自参考 spring cloud 官方文档

Spring Cloud alibaba 官网地址

示例代码地址

服务器nacos 地址 http://47.99.209.72:8848/nacos

往期地址 spring cloud alibaba 地址

spring cloud alibaba 简介

Spring Cloud Alibaba (nacos 注册中心搭建)

Spring Cloud Alibaba 使用nacos 注册中心

Spring Cloud Alibaba nacos 配置中心使用

spring cloud 网关服务

Spring Cloud zuul网关服务 一

Spring Cloud 网关服务 zuul 二

Spring Cloud 网关服务 zuul 三 动态路由

Spring Cloud alibaba网关 sentinel zuul 四 限流熔断

Spring Cloud gateway 网关服务 一

Spring Cloud gateway 网关服务二 断言、过滤器

Spring Cloud gateway 三 自定义过滤器GatewayFilter

Spring Cloud gateway 网关四 动态路由

Spring Cloud gateway 五 Sentinel整合

如何喜欢可以关注分享本公众号。
file

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。转载请附带公众号二维码

posted @ 2019-11-13 12:48  程序员你大爷  阅读(...)  评论(... 编辑 收藏