Spring Cloud Alibaba 架构-Sentinel整合nacos和gateway

官网地址

sentinel官网: https://github.com/alibaba/Sentinel/wiki/主页

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:

yml 复制代码
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

bash 复制代码
docker-compose up -d

jar启动

  1. 下载Sentinel JAR包
  • 访问Sentinel的官方GitHub地址或Maven仓库,下载适合您项目的Sentinel JAR包。例如,sentinel-dashboard-xxx.jar。
  1. 配置Nacos数据源:
  • 在Spring Cloud项目中,需要添加Nacos数据源相关的Maven依赖。例如:
xml 复制代码
<dependency>  
    <groupId>com.alibaba.csp</groupId>  
    <artifactId>sentinel-datasource-nacos</artifactId>  
    <version>您的Sentinel版本</version>  
</dependency>
  • 在项目的配置文件(如application.properties或application.yml)中,配置Nacos数据源的相关参数,如Nacos服务器的地址、端口、命名空间、数据ID等。例如:
xml 复制代码
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,并指定配置文件(如果需要)。例如:
bash 复制代码
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

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 的依赖。

xml 复制代码
<!-- 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)、限流规则、熔断规则等。

yml 复制代码
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

java 复制代码
@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);
    }
}
相关推荐
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
菜菜-plus2 小时前
分布式,微服务,SpringCloudAlibaba,nacos,gateway,openFeign
java·分布式·微服务·nacos·gateway·springcloud·openfeign
七月在野,八月在宇,九月在户2 小时前
前端--> nginx-->gateway产生的跨域问题分析
前端·nginx·gateway
CodingBrother2 小时前
软考之面向服务架构SOA-通信方法
架构
码哥字节3 小时前
重生之从零设计 MySQL 架构
数据库·mysql·架构
wclass-zhengge12 小时前
系统架构(01架构的特点,本质...)
架构·系统架构
白总Server15 小时前
UI架构解说
大数据·服务器·网络·数据库·web安全·架构·数据库架构
努力进修15 小时前
“高级Java编程复习指南:深入理解并发编程、JVM优化与分布式系统架构“
java·jvm·架构
你的微笑,乱了夏天16 小时前
微服务链路追踪skywalking安装
分布式·后端·中间件·架构·skywalking
985小水博一枚呀18 小时前
【深度学习目标检测|YOLO算法4-4】YOLO家族进化史:从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析——工业领域
网络·人工智能·深度学习·算法·yolo·目标检测·架构