sentinel网关限流

sentinel 网关限流

官方教程

基本使用配置
  • 需要引入的包

    本人用的版本:spring cloud Hoxton.SR11 spring cloud alibaba 2.2.6.RELEASE

    不同版本可能会导致sentinel无法加载nacos配置的流控规则的奇怪bug

           <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
            dependency>
    
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-sentinel-gatewayartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-gatewayartifactId>
            dependency>
           
            <dependency>
                <groupId>com.alibaba.cspgroupId>
                <artifactId>sentinel-datasource-nacosartifactId>
            dependency>
           	 
    
  • 启动sentinel控制台

    这里使用的sentinel-dashboard-1.8.0.jar

    java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
    
  • 网关中的配置如下 aplication.yml

    这里配置了两个datasource,一个加载网关流控规则,一个加载网关自定义api

    代码中会根据rule-type来区分,gw-flow表示网关流控规则 ,gw-api-group表示自定义api

    server:
      port: 8082
    spring:
      cloud:
        gateway:
          enabled: true
          discovery:
            locator:
              lower-case-service-id: true
          routes:
            - id: httpbin_route
              uri: http://aiforcare.com/
              predicates:
                - Path=/**
        sentinel:
          datasource:
            ds1:  #从nacos读取流控规则
              nacos:
                server-addr: 192.168.1.28:8848
                data-id: sentinel.json
                group-id: DEFAULT_GROUP
                data-type: json
                rule-type: gw-flow
                namespace: 3d55ade7-7100-400d-a707-eafdaa58f41d
            ds2:   #从nacos读取api-definition
              nacos:
                server-addr: 192.168.1.28:8848
                data-id: api-group.json
                group-id: DEFAULT_GROUP
                data-type: json
                rule-type: gw-api-group
                namespace: 3d55ade7-7100-400d-a707-eafdaa58f41d
    
  • nacos中配置 注意要用数组

    ​ sentinel.json

     [
    	{
      		"burst": 0,
      		"controlBehavior": 0,  //0-表示快速失败
      		"count": 10.0,  
      		"grade": 1,  //按qps限流
      		"intervalSec": 1,
      		"maxQueueingTimeoutMs": 500,
      		"paramItem": {
      			"index": 0,
      			"matchStrategy": 0,
      			"parseStrategy": 0
      		},
      		"resource": "cos",  //api名称
      		"resourceMode": 1
      	}
      ]
    

    api-group.json

      [
      	{
      		"apiName": "cos1",  //api名称
      		"predicateItems": [
      			{
      				"matchStrategy": 0,    //精确匹配
      				"pattern": "/acl/user/user2"
      			}
      		]
      	},
      	{
      		"apiName": "cos",
      		"predicateItems": [
      			{
      				"matchStrategy": 0,
      				"pattern": "/order/userOrder/view"
      			}
      		]
      	}
      ]
    
  • 网关服务启动配置参数

    -Dcsp.sentinel.dashboard.server=127.0.0.1:8080  #sentinel控制台地址
    -Dproject.name=springcloud-gateway  #应用名称
    -Dcsp.sentinel.api.port=8888    #sentinel控制台与客户端连接的端口
    -Dcsp.sentinel.app.type=1   #1表示是网关流控  这个必须设置  很重要
    
怎么实现sentinel控制台配置持久化到nacos中

如果没有做持久化,每次服务重启会导致之前在sentinel控制台配置的全部消失,因为它只是保存在内存中

实现代码如下

  1. 自定义一个WritableDataSource

    package com.gaorong.orm;
    
    import com.alibaba.csp.sentinel.datasource.WritableDataSource;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.nacos.api.NacosFactory;
    import com.alibaba.nacos.api.PropertyKeyConst;
    import com.alibaba.nacos.api.config.ConfigService;
    import com.alibaba.nacos.api.exception.NacosException;
    import lombok.extern.slf4j.Slf4j;
    
    import java.util.Properties;
    
    /**
     * @author leic .
     * @date 2021/8/6 15:27
     */
    @Slf4j
    public class NacosWritableDataSource<T> implements WritableDataSource<T> {
    
    
        private ConfigService configService = null;
    
        private String groupId;
    
        private String dataId;
    
    
        public NacosWritableDataSource(String serverAddr, String groupId, String dataId,
                                       String nameSpace) {
            this.groupId = groupId;
            this.dataId = dataId;
            Properties properties = buildProperties(serverAddr, nameSpace);
            try {
                this.configService = NacosFactory.createConfigService(properties);
            } catch (NacosException e) {
                log.info("初始化nacos客户端失败:", e);
                throw new RuntimeException(e.getMessage());
            }
    
        }
    
        @Override
        public void write(T value) throws Exception {
            try {
                String convert = JSON.toJSONString(value);
                  //持久化配置到nacos,每一次sentinel规则更新都会给到全量(api或网关流控)的配置信息
                configService.publishConfig(dataId, groupId, convert);
            } catch (NacosException e) {
                log.error("error:", e);
            }
        }
    
        @Override
        public void close() throws Exception {
    
        }
    
        private static Properties buildProperties(String serverAddr, String namespace) {
            Properties properties = new Properties();
            properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverAddr);
            properties.setProperty(PropertyKeyConst.NAMESPACE, namespace);
            return properties;
        }
    }
    
    
  2. 将自定义的WritableDataSource绑定到api及流控规则更新的处理类中

    package com.gaorong.orm;
    
    import com.alibaba.cloud.sentinel.SentinelProperties;
    import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration;
    import com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties;
    import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
    import com.alibaba.csp.sentinel.adapter.gateway.common.command.UpdateGatewayApiDefinitionGroupCommandHandler;
    import com.alibaba.csp.sentinel.adapter.gateway.common.command.UpdateGatewayRuleCommandHandler;
    import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @author leic .
     * @date 2021/8/6 16:26
     */
    @Service
    public class SentinelPersistHandler implements ApplicationListener<ContextRefreshedEvent> {
        @Resource
        private SentinelProperties sentinelProperties;
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            initGateWayApiDefinition();
            initGatewayFlowRule();
        }
    
        private void initGatewayFlowRule() {
            //ds1 与配置文件中对应
            NacosDataSourceProperties nacosProperty = getNacosDataSourceProperties("ds1");
            NacosWritableDataSource<Set<GatewayFlowRule>> nacosWritableDataSource
                    = new NacosWritableDataSource(nacosProperty.getServerAddr()
                    , nacosProperty.getGroupId(), nacosProperty.getDataId(), nacosProperty.getNamespace());
            //网关流控规则处理类
            UpdateGatewayRuleCommandHandler.setWritableDataSource(nacosWritableDataSource);
        }
    
        private NacosDataSourceProperties getNacosDataSourceProperties(String key) {
            Map<String, DataSourcePropertiesConfiguration> datasource = sentinelProperties.getDatasource();
            DataSourcePropertiesConfiguration configuration
                    = datasource.get(key);
            NacosDataSourceProperties nacosProperty = configuration.getNacos();
            return nacosProperty;
        }
    
        private void initGateWayApiDefinition() {
            //ds2 与配置文件中对应
            NacosDataSourceProperties nacosProperty = getNacosDataSourceProperties("ds2");
            NacosWritableDataSource<Set<ApiDefinition>> nacosWritableDataSource
                    = new NacosWritableDataSource(nacosProperty.getServerAddr()
                    , nacosProperty.getGroupId(), nacosProperty.getDataId(), nacosProperty.getNamespace());
    /**api更新处理类**/       UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(nacosWritableDataSource);
        }
    }
    
    

你可能感兴趣的:(gateway)