SpringCloud Alibaba Sentinel限流熔断降级(四)--------------客户端配置动态数据源Nacos获取限流规则

前面我们介绍了sentinel控制台以及客户端的启动,并且实现了在控制台添加流控以及熔断规则,并且将规则发送给客户端。但是,将客户端重启,我们会发现,我们之前设置的规则将会丢失,这是因为客户端将规则保存在内存中,并没有将其持久化,因而,这样并不适用于生产环境。

下面我们介绍一下Sentinel采用Nacos数据源,将规则持久化:
控制台以及Nacos可以按照之前的博客自行启动:


启动Sentinel控制台https://blog.csdn.net/qq_26932225/article/details/88907123

启动Nacos Server https://blog.csdn.net/qq_26932225/article/details/86536837

本文的客户端demo:https://github.com/xujingle1995/Learn-SpringCloudAlibaba/tree/master/sentinel-client-nacos

Sentinel数据源 

Sentinel的数据源可以通过多种方式加载:json、xml文件;zookeeper;apollo;nacos;并且可以多种数据源同时使用。

动态数据源:DataSource 扩展常见的实现方式有:

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

要具体了解可以查看官网的介绍:https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95

在生产环境下推荐使用推模式, 这需要设置客户端,并且需要修改Sentinel控制台的源码

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

SpringCloud Alibaba Sentinel限流熔断降级(四)--------------客户端配置动态数据源Nacos获取限流规则_第1张图片


下面我们先介绍客户端的Nacos动态数据源配置,Nacos数据源熔断规则发生变化,自动推送到Sentinel客户端:

Sentinel客户端配置

  • 引入依赖 

    		
    			org.springframework.boot
    			spring-boot-starter-web
    		
    		
    			org.springframework.boot
    			spring-boot-devtools
    			runtime
    		
    		
    			org.springframework.boot
    			spring-boot-starter-test
    			test
    		
    
    		
    		
    			org.springframework.cloud
    			spring-cloud-starter-alibaba-sentinel
    			0.2.1.RELEASE
    		
    		
    		
    			org.springframework.boot
    			spring-boot-starter-actuator
    		
    		
    		
    			com.alibaba.csp
    			sentinel-datasource-nacos
    			1.5.1
    		

     

  • 修改配置文件

    # 设置sentinel客户端http server与控制台之间通信的端口
    spring.cloud.sentinel.transport.port=8731
    
    # 设置控制台地址
    spring.cloud.sentinel.transport.dashboard=localhost:8080
    
    # 本工程监听端口
    server.port=8090
    
    #本工程名
    spring.application.name=sentinel-client
    
    # 设置Sentinel Nacos数据源配置;其中ds2是数据源名,可以自行随意修改
    # Nacos数据源地址(需要启动一台Nacos Server)
    spring.cloud.sentinel.datasource.ds2.nacos.server-addr=172.16.10.40:8848
    spring.cloud.sentinel.datasource.ds2.nacos.dataId=nacos-datasource.json
    spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
    spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
    spring.cloud.sentinel.datasource.ds2.nacos.rule-type=flow
    
    # 进行该项设置,可以通过http://localhost:8090/actuator/sentinel访问到该客户端的所有规则
    management.endpoints.web.exposure.include=*

     

  • 添加Nacos数据源配置类
     

    package com.xjl.sentinel.config;
    
    import java.util.List;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.alibaba.sentinel.SentinelProperties;
    import org.springframework.cloud.alibaba.sentinel.datasource.config.NacosDataSourceProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
    import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.TypeReference;
    
    
    @Configuration
    public class DataSourceInitFunc {
    
    	Logger logger = LoggerFactory.getLogger(DataSourceInitFunc.class);
    
    	@Autowired
    	private SentinelProperties sentinelProperties;
    
    	@Bean
    	public DataSourceInitFunc init() throws Exception {
    
    		logger.info("[NacosSource初始化,从Nacos中获取熔断规则]");
    
    		sentinelProperties.getDatasource().entrySet().stream().filter(map -> {
    			return map.getValue().getNacos() != null;
    		}).forEach(map -> {
    			NacosDataSourceProperties nacos = map.getValue().getNacos();
    			ReadableDataSource> flowRuleDataSource = new NacosDataSource<>(nacos.getServerAddr(),
    					nacos.getGroupId(), nacos.getDataId(),
    					source -> JSON.parseObject(source, new TypeReference>() {
    					}));
    			FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    		});
    		return new DataSourceInitFunc();
    	}
    }
    

     

  • 添加资源
     

    package com.xjl.sentinel.handler;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    
    public class SentinelExceptionHandler {
    	
    	final static Logger logger = LoggerFactory.getLogger(SentinelExceptionHandler.class);
    	
    	public static String blockExceptionHandle(String name, BlockException exception) {
    		exception.printStackTrace();
    		logger.info("sentinel 熔断处理 {}", "SentinelExceptionHandler");
    		return "Sentinel 熔断处理函数";
    	}
    
    }
    
    package com.xjl.sentinel.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.alibaba.csp.sentinel.EntryType;
    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
    import com.xjl.sentinel.handler.SentinelExceptionHandler;
    import com.xjl.sentinel.service.FallbackService;
    
    @RestController
    public class SentinelTestController {
    	
    	@Autowired
    	private FallbackService service;
    
    	@SentinelResource(value = "hello", entryType = EntryType.OUT, blockHandlerClass = SentinelExceptionHandler.class, blockHandler = "blockExceptionHandle")
    	@GetMapping("/hello/{name}")
    	public String hello(@PathVariable("name") String name) {
    		System.out.println(name);
    		return "hello " + name;
    	}
    }
    

     

  • Nacos中添加熔断规则

    规则文件可以是json文件;也可以是text文件。 

    [
        {
            "app": "sentinel-client",
            "clusterConfig": {
                "fallbackToLocalWhenFail": true,
                "sampleCount": 10,
                "strategy": 0,
                "thresholdType": 0,
                "windowIntervalMs": 1000
            },
            "clusterMode": false,
            "controlBehavior": 0,
            "count": 3.0,
            "gmtCreate": 1554541390168,
            "gmtModified": 1554543573961,
            "grade": 1,
            "id": 4,
            "ip": "172.16.10.167",
            "limitApp": "default",
            "port": 8731,
            "resource": "hello",
            "strategy": 0
        }
    ]

    其中:
    app的值修改为你的应用名(spring.application.name)
    count可以自行修改,我这里是3.0(每秒钟最多请求3次,否则熔断)

  • 测试

启动客户端,请求http://localhost:8090/hello/xjl,不断刷新,若一秒钟之内点击超过3次,就会熔断

可以自行下载代码查看: https://github.com/xujingle1995/Learn-SpringCloudAlibaba/tree/master/sentinel-client-nacos

后面文章再介绍控制台的修改,实现控制台将熔断规则推送到Nacos数据源

你可能感兴趣的:(springcloud,alibaba)