ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringCloudGateway基于Sentinel的限流

2022-04-20 09:04:41  阅读:315  来源: 互联网

标签:category service SpringCloudGateway add 限流 Sentinel new API


SpringCloudGateway基于Sentinel的限流

 

Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。

 

 Sentinel介绍:

从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:          *  route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId      *  自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组   Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则自定义 API 的实体和管理逻辑:      *  GatewayFlowRule :网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同          route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的          限流。      *  ApiDefinition :用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以         定义一个 API 叫 my_api ,请求 path 模式为 /foo/** 和 /baz/** 的都归到 my_api 这个 API         分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。

 

 

 

(1)环境搭建 

导入Sentinel 的响应依赖 
<!-- sentinel限流依赖 -->
<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
   <version>1.7.2</version>
</dependency>

 

(2)编写配置类 

package com.kerry.gateway.filter;

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

    /**
     * 配置限流的异常处理器:SentinelGatewayBlockExceptionHandler
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers,serverCodecConfigurer);
    }
    /**
     * 配置限流过滤器
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }
    /**
     * 配置初始化的限流参数
     */
    @PostConstruct
    public void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
//        rules.add( new GatewayFlowRule("category-service") //资源名称    //普通全局限流
//                        .setCount(1) // 限流阈值
//                        .setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
//        );

        //http://localhost:8001/admin/category/demo.do/1?id=1  当链接带有参数id时,会匹配到限流中
        //http://localhost:8001/admin/category/demo.do/1   如果没有带参数id时,不会被匹配进限流中。
//        rules.add(new GatewayFlowRule("category-service") //参数限流
//                .setCount(1)
//                .setIntervalSec(1)
//                .setParamItem(new GatewayParamFlowItem()
//                    .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM).setFieldName("id")
//                )
//        );

        //上面的话是直接对资源进行限流

        //下面是通过自定义api分组进行限流 其里面的资源都在下面进行设置好了对应的匹配路径.
        rules.add(new GatewayFlowRule("category_api").setCount(1).setIntervalSec(1));
        rules.add(new GatewayFlowRule("headline_api").setCount(1).setIntervalSec(1));
        GatewayRuleManager.loadRules(rules);
    }

    // 自定义API分组
    @PostConstruct
    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();

        ApiDefinition api1 = new ApiDefinition("category_api")
        .setPredicateItems(new HashSet<ApiPredicateItem>() {{
            //以/product-service/product 开头的请求
            add(new ApiPathPredicateItem().setPattern("/admin/category/**").
            setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
        }});

        ApiDefinition api2 = new ApiDefinition("headline_api")
        .setPredicateItems(new HashSet<ApiPredicateItem>() {{
            ///order-service/order 完成的url路径匹配
            //add(new ApiPathPredicateItem().setPattern("/order-service/order"));
            //add(new ApiPathPredicateItem().setPattern("/order/buy"));
            add(new ApiPathPredicateItem().setPattern("/admin/headline/**").
            setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
        }});
        definitions.add(api1);
        definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    //自定义异常提示
    @PostConstruct
    public void initBlockHandlers() {
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Map map = new HashMap<>();
                map.put("code", 001);
                map.put("message", "对不起,接口限流了");
                return ServerResponse.status(HttpStatus.OK).//状态码200
                        contentType(MediaType.APPLICATION_JSON_UTF8).//application/json;charset=UTF-8
                        body(BodyInserters.fromObject(map));
            }
        };
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
}

(3)网关配置 

server:
  port: 8001

spring:
  application:
    name: server-gateway #服务名称
  cloud:
    gateway:
      routes:
      - id: category-service
        uri: lb://service-category
        predicates:
        - Path=/category/**,/admin/category/**
        filters: #限流功能
        - RewritePath=/admin/category/(?<segment>.*), /admin/category/$\{segment}
      - id: headline-service
        uri:  lb://service-headline
        predicates:
        - Path=/headline/**,/admin/headline/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka 
      registry-fetch-interval-seconds: 5 # 获取服务列表的周期:5s
  instance:
    prefer-ip-address: true #使用ip注册
    ip-address: 127.0.0.1

 

 

 

 

 

标签:category,service,SpringCloudGateway,add,限流,Sentinel,new,API
来源: https://www.cnblogs.com/zcl1116/p/16168330.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有