gateway整合sentinel限流

官方文档:https://github.com/alibaba/Sentinel/wiki/网关限流

从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:

  • route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
  • 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组

1.快速开始

使用时需引入依赖:

java 复制代码
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel‐spring‐cloud‐gateway‐adapter</artifactId>
<version>x.y.z</version>
</dependency>

接入sentinel dashboard,添加yml配置

yaml 复制代码
spring:
application:
name: mall‐gateway‐sentinel‐demo
#配置nacos注册中心地址
cloud:
nacos:
discovery:
server‐addr: 127.0.0.1:8848
 sentinel:
 transport:
 # 添加sentinel的控制台地址
 dashboard: 127.0.0.1:8080

使用时只需注入对应的 SentinelGatewayFilter 实例以及SentinelGatewayBlockExceptionHandler 实例即可

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;
    }

    /**
     * 限流异常处理器
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    /**
     * 限流过滤器
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

}

用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则

GatewayConfiguration中添加

java 复制代码
@PostConstruct
    public void doInit() {
        //初始化自定义的API
        initCustomizedApis();
        //初始化网关限流规则
        initGatewayRules();
        //自定义限流异常处理器
        initBlockRequestHandler();
    }

    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        ApiDefinition api = new ApiDefinition("user_service_api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/user/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        definitions.add(api);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        //resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
        //count:限流阈值
        //intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
        rules.add(new GatewayFlowRule("order_route")
                .setCount(2)
                .setIntervalSec(1)
        );
        rules.add(new GatewayFlowRule("user_service_api")
                .setCount(2)
                .setIntervalSec(1)
        );

        // 加载网关规则
        GatewayRuleManager.loadRules(rules);
    }

    private void initBlockRequestHandler() {
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
                HashMap<String, String> result = new HashMap<>();
                result.put("code",String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
                result.put("msg", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());

                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(result));
            }
        };
        //设置自定义异常处理器
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }

2.网关流控控制台

Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置。

在 API Gateway 端,用户只需要在原有启动参数的基础上添加如下启动参数即可标记应用为 API Gateway 类型:

yaml 复制代码
# 注:通过 Spring Cloud Alibaba Sentinel 自动接入的 API Gateway 整合则无需此参数
-Dcsp.sentinel.app.type=1

3.网关流控实现原理

4.网关高可用

为了保证 Gateway 的高可用性,可以同时启动多个 Gateway 实例进行负载,在 Gateway 的上游使用 Nginx 或者 F5 进行负载转发以达到高可用。

相关推荐
CodeAmaz1 天前
自定义限流方案(基于 Redis + 注解)
java·redis·限流·aop·自定义注解
半旧夜夏2 天前
【Gateway】服务调用和网关配置攻略
java·spring boot·spring cloud·gateway
小坏讲微服务3 天前
Nginx集群与SpringCloud Gateway集成Nacos的配置指南
spring boot·nginx·spring cloud·gateway
小坏讲微服务3 天前
使用 Spring Cloud Gateway 实现集群
java·spring boot·分布式·后端·spring cloud·中间件·gateway
没有bug.的程序员3 天前
Spring Cloud Gateway 路由与过滤器机制
java·开发语言·spring boot·spring·gateway
serendipity_hky4 天前
【微服务 - easy视频 | day01】准备工具+gateway网关及路由至内部服务
java·微服务·架构·gateway·springcloud
IT小哥哥呀7 天前
Jenkins + Docker 打造自动化持续部署流水线
docker·微服务·自动化·jenkins·springboot·高并发·限流
Owen__z8 天前
GEE统计特定区域特定时间上的Landsat/Sentinel的影像信息
python·sentinel·gee·geemap·landsat
我要去腾讯8 天前
Springcloud核心组件之Sentinel详解
java·spring cloud·sentinel
三口吃掉你8 天前
微服务之网关(Spring Cloud Gateway)
java·网关·微服务·gateway