官网地址

sentinel官网: https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5
sentinel 下载地址: https://github.com/alibaba/Sentinel/releases
nacos官网: https://nacos.io/zh-cn/docs/deployment.html
nacos下载地址: https://github.com/alibaba/nacos/releases

部署

容器部署

简化的示例,展示了如何在Docker Compose文件中定义Sentinel和Nacos:

version: '3'  
services:  
  nacos:  
    image: nacos/nacos-server:latest  
    ports:  
      - "8848:8848"  
    environment:  
      - MODE=standalone  
      # 其他Nacos配置...  
  
  sentinel:  
    image: your-sentinel-image:latest  # 替换为您的Sentinel镜像  
    ports:  
      - "8080:8080"  # Sentinel控制台端口  
    depends_on:  
      - nacos  
    environment:  
      - SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_NAME=nacos  
      - SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_TYPE=nacos  
      - SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_NAMESPACE=public  # 您的Nacos命名空间  
      - SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_SERVER-ADDR=nacos:8848  # 指向Nacos服务的地址  
      # 其他Sentinel配置...

启动Docker Compose

docker-compose up -d

jar启动

  1. 下载Sentinel JAR包
  • 访问Sentinel的官方GitHub地址或Maven仓库,下载适合您项目的Sentinel JAR包。例如,sentinel-dashboard-xxx.jar。
  1. 配置Nacos数据源:
  • 在Spring Cloud项目中,需要添加Nacos数据源相关的Maven依赖。例如:
<dependency>  
    <groupId>com.alibaba.csp</groupId>  
    <artifactId>sentinel-datasource-nacos</artifactId>  
    <version>您的Sentinel版本</version>  
</dependency>
  • 在项目的配置文件(如application.properties或application.yml)中,配置Nacos数据源的相关参数,如Nacos服务器的地址、端口、命名空间、数据ID等。例如:
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=127.0.0.1:8848  
spring.cloud.sentinel.datasource.ds1.nacos.dataId=sentinel-rules  
spring.cloud.sentinel.datasource.ds1.nacos.group=DEFAULT_GROUP  
spring.cloud.sentinel.datasource.ds1.nacos.namespace=public  
# 其他配置项...
  1. 启动Sentinel:
  • 在命令行中,进入包含Sentinel JAR包的目录。
  • 使用java -jar命令启动Sentinel,并指定配置文件(如果需要)。例如:
java -jar sentinel-dashboard-xxx.jar --spring.config.location=classpath:application.properties

注意:这里假设已经将Nacos数据源的配置写入了application.properties文件,并且该文件位于类路径(classpath)下。如果配置文件位置不同,需要相应地修改–spring.config.location参数的值。

DEMO

官网demo地址:https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-nacos-datasource/src/main/java/com/alibaba/csp/sentinel/demo/datasource/nacos/NacosDataSourceDemo.java

public class NacosDataSourceDemo {

    private static final String KEY = "TestResource";
    // nacos server ip
    private static final String remoteAddress = "localhost:8848";
    // nacos group
    private static final String groupId = "Sentinel_Demo";
    // nacos dataId
    private static final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
    // if change to true, should be config NACOS_NAMESPACE_ID
    private static boolean isDemoNamespace = false;
    // fill your namespace id,if you want to use namespace. for example: 0f5c7314-4983-4022-ad5a-347de1d1057d,you can get it on nacos's console
    private static final String NACOS_NAMESPACE_ID = "${namespace}";

    public static void main(String[] args) {
        if (isDemoNamespace) {
            loadMyNamespaceRules();
        } else {
            loadRules();
        }

        // Assume we config: resource is `TestResource`, initial QPS threshold is 5.
        FlowQpsRunner runner = new FlowQpsRunner(KEY, 1, 100);
        runner.simulateTraffic();
        runner.tick();
    }

    private static void loadRules() {
        ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
                source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                }));
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }

    private static void loadMyNamespaceRules() {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, remoteAddress);
        properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);

        ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, groupId, dataId,
                source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                }));
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }

}

集成Spring Cloud Gateway

步骤:
1. 添加依赖
在 Spring Cloud Gateway 项目的 pom.xml 文件中,添加 Sentinel 和 Spring Cloud Alibaba 的相关依赖。这通常包括 Spring Cloud Alibaba Sentinel 的依赖以及 Spring Cloud Gateway 的依赖。

<!-- Spring Cloud Gateway 核心 -->  
<dependency>  
    <groupId>org.springframework.cloud</groupId>  
    <artifactId>spring-cloud-starter-gateway</artifactId>  
</dependency>  

<!-- Spring Cloud Alibaba Sentinel -->  
<dependency>  
    <groupId>com.alibaba.cloud</groupId>  
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>  
    <version>你的版本号</version>  
</dependency>

2. 配置Sentinel
在 application.yml 或 application.properties 配置文件中,配置 Sentinel 的相关参数,如数据源(例如 Nacos)、限流规则、熔断规则等。

spring:  
  cloud:  
    sentinel:  
      transport:  
        dashboard: localhost:8080 # Sentinel 控制台地址  
        port: 8719 # Sentinel 客户端与控制台通信的端口,默认8719  
      datasource:  
        # 这里可以配置 Nacos 数据源,用于动态加载限流规则等  
        flow:  
          nacos:  
            server-addr: localhost:8848  
            dataId: ${spring.application.name}-flow-rules  
            groupId: DEFAULT_GROUP  
            namespace: public  
            rule-type: flow  

# 其他 Sentinel 和 Gateway 配置...

3. 设置限流和熔断规则
可以通过 Sentinel 控制台动态设置限流和熔断规则,也可以通过配置文件静态设置。在 Sentinel 控制台中,可以创建流控规则、熔断规则等,并实时查看和修改它们。
4. 启动于测试
启动 Spring Cloud Gateway 应用,并通过浏览器或 Postman 等工具发送请求来测试限流和熔断功能是否生效。可以观察 Sentinel 控制台中的实时监控数据,以验证限流和熔断规则是否按预期工作。

DEMO

官网地址: https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-spring-cloud-gateway/pom.xml

@Configuration
public class GatewayConfiguration {

    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    @Bean
    @Order(-1)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    @PostConstruct
    public void doInit() {
        initCustomizedApis();
        initGatewayRules();
    }

    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        ApiDefinition api1 = new ApiDefinition("some_customized_api")
            .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                add(new ApiPathPredicateItem().setPattern("/ahas"));
                add(new ApiPathPredicateItem().setPattern("/product/**")
                    .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
            }});
        ApiDefinition api2 = new ApiDefinition("another_customized_api")
            .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                add(new ApiPathPredicateItem().setPattern("/**")
                    .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
            }});
        definitions.add(api1);
        definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(new GatewayFlowRule("aliyun_route")
            .setCount(10)
            .setIntervalSec(1)
        );
        rules.add(new GatewayFlowRule("aliyun_route")
            .setCount(2)
            .setIntervalSec(2)
            .setBurst(2)
            .setParamItem(new GatewayParamFlowItem()
                .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)
            )
        );
        rules.add(new GatewayFlowRule("httpbin_route")
            .setCount(10)
            .setIntervalSec(1)
            .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
            .setMaxQueueingTimeoutMs(600)
            .setParamItem(new GatewayParamFlowItem()
                .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
                .setFieldName("X-Sentinel-Flag")
            )
        );
        rules.add(new GatewayFlowRule("httpbin_route")
            .setCount(1)
            .setIntervalSec(1)
            .setParamItem(new GatewayParamFlowItem()
                .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                .setFieldName("pa")
            )
        );
        rules.add(new GatewayFlowRule("httpbin_route")
            .setCount(2)
            .setIntervalSec(30)
            .setParamItem(new GatewayParamFlowItem()
                .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                .setFieldName("type")
                .setPattern("warn")
                .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_CONTAINS)
            )
        );

        rules.add(new GatewayFlowRule("some_customized_api")
            .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
            .setCount(5)
            .setIntervalSec(1)
            .setParamItem(new GatewayParamFlowItem()
                .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                .setFieldName("pn")
            )
        );
        GatewayRuleManager.loadRules(rules);
    }
}
Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐