前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloudGateway笔记(9)-限流

SpringCloudGateway笔记(9)-限流

作者头像
yingzi_code
发布2019-08-30 22:06:02
2.3K0
发布2019-08-30 22:06:02
举报

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/yingziisme/article/details/94591109

使用SpringCloudGateway的重要功能 – 限流过滤器

网关的重要功能还有限流

SpringCloudGateway提供了一个默认的限流过滤器RequestRateLimiter,默认通过Redis+Lua技术实现高并发和高性能的限流方案,源码参考RedisRateLimiter和META-INF/scripts/request_rate_limiter.lua

实际使用需要引用spring-boot-starter-data-redis-reactive的jar包自动开启该filter

代码语言:javascript
复制
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

配置文件配置

代码语言:javascript
复制
        - id: spring-cloud-client-demo2
          uri: lb://spring-cloud-client-demo
          predicates:
            - Path=/cloud/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1
                redis-rate-limiter.burstCapacity: 1
                key-resolver: "#{@myKeyResolver}"

自定义key的bean

代码语言:javascript
复制
    /**
     * 自定义限流标志的key
     * exchange对象中获取请求信息,用户信息等
     *
     * @return key
     */
    @Bean
    KeyResolver myKeyResolver() {
//        return exchange -> Mono.just(System.nanoTime() + "");
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
    }

配置测试请求

代码语言:javascript
复制
    @GetMapping("/weight")
    public String weight(@RequestParam String param) {
        log.info("aaaa: {}", param);
        return "aaa";
    }
代码语言:javascript
复制
@GetMapping("/rate")
    public void rate(@RequestParam int size) {

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity httpEntity = new HttpEntity(httpHeaders);
        for (int i = 0; i < size; i++) {
            demoService.rate(httpEntity);
        }
    }
代码语言:javascript
复制
@Slf4j
@Service
public class DemoService {

    @Autowired
    private RestTemplate restTemplate;

    @Async
    public void rate(HttpEntity httpEntity) {
        try {
            ResponseEntity<String> responseEntity = restTemplate.exchange(new URI("http://localhost:10001/cloud/demo/weight?param=mt"), HttpMethod.GET, httpEntity, String.class);
            log.info("===={}==", responseEntity);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
}

使用POSTMAN发送请求

GET http://localhost:10001/cloud/demo/rate?size=2

在这里插入图片描述
在这里插入图片描述

发送请求后 可以到看到后台打印

第一个请求正常响应,而第二个请求抛出了429 Too Many Requests的错误

代码语言:javascript
复制
2019-06-29 22:13:14.161  INFO 1112 --- [nio-8801-exec-5] c.m.d.client.controller.DemoController   : aaaa: mt
2019-06-29 22:13:14.190 ERROR 1112 --- [        task-21] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.mt.demo.client.service.DemoService.rate(org.springframework.http.HttpEntity)

org.springframework.web.client.HttpClientErrorException$TooManyRequests: 429 Too Many Requests
	at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:97) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:102) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:778) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:710) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:598) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at com.mt.demo.client.service.DemoService.rate(DemoService.java:31) ~[classes/:na]
	at com.mt.demo.client.service.DemoService$$FastClassBySpringCGLIB$$1c9d4507.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_191]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_191]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_191]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_191]

同时在redis用MONITOR命令监控 可以看到redis的数据

代码语言:javascript
复制
1561807184.849478 [1 222.125.214.54:59510] "EVALSHA" "eec77786d43c65f7fd568900b5d2b63b692318dc" "2" "request_rate_limiter.{0:0:0:0:0:0:0:1}.tokens" "request_rate_limiter.{0:0:0:0:0:0:0:1}.timestamp" "1" "1" "1561807184" "1"
1561807184.849534 [1 lua] "get" "request_rate_limiter.{0:0:0:0:0:0:0:1}.tokens"
1561807184.849545 [1 lua] "get" "request_rate_limiter.{0:0:0:0:0:0:0:1}.timestamp"
1561807184.849557 [1 lua] "setex" "request_rate_limiter.{0:0:0:0:0:0:0:1}.tokens" "2" "0"
1561807184.849570 [1 lua] "setex" "request_rate_limiter.{0:0:0:0:0:0:0:1}.timestamp" "2" "1561807184"
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com