GateWay结合Redis实现令牌桶限流

首先谈谈为什么要限流,有哪些限流方案?

限流是指控制系统中的流量,以保护系统免于过载或崩溃。在高并发、大数据量和分布式场景下,限流可以保护系统稳定性,防止由于流量超负荷而导致的服务降级或崩溃。

常见的限流方案包括:

  1. 令牌桶算法:系统会根据一个固定速率往令牌桶(Token Bucket)中添加令牌,每次请求需要获取一个令牌,当没有令牌时则请求被拒绝。
  2. 漏桶算法:系统会按照一个固定速率从漏桶中漏出请求,当请求到达时需要先进入漏桶中等待,当漏桶为空则请求被拒绝。
  3. 计数器算法:系统会记录单位时间内服务响应请求的次数,当到达设定的阈值时则请求被拒绝。
  4. 时间窗口算法:系统将时间分成多个窗口,每个窗口有一个最大请求量的限制,当当前窗口内的请求量超过该限制时则请求被拒绝。
  5. 基于权重的算法:系统根据业务需求和实际情况,对不同的请求设置不同的权重,在高流量时优先处理权重高的请求,避免因低优先级请求过多造成整体系统拥塞。

以上这些算法都可以通过在服务器端配置来实现限流,但不同的算法适用于不同的业务场景,需要根据实际情况做出选择。

在限流中有两个概念需要了解

阈值:在一个单位时间内允许的请求量。如 QPS 限制为10,说明 1 秒内最多接受 10 次请求。

拒绝策略:超过阈值的请求的拒绝策略,常见的拒绝策略有直接拒绝、排队等待等。

为什么限流

是防止用户恶意刷新接口,因为部署在外部服务器,并且我们采用websocket的接口实现的,公司没有对硬件升级,导致程序时长崩溃,为了解决这个问题,请教公司的大佬,提出一个方案,限流操作。

但是最后找到原因所在,解决了,吞吐量1万6左右,用的测试服务器,进行测试的,我开发的笔记本进行压测,工具是Jmeter,结果我的电脑未响应,卡了,服务器还没有挂。

常见的限流:

Netflix的hystrix

阿里系开源的sentinel

说白了限流,为了处理高并发接口那些方式:队列,线程,线程池,消息队列、 kafka、中间件、sentinel:直接拒绝、Warm Up、匀速排队等

技术层面:

判断是否有相同的请求,可以通过自身缓存挡住相同请求

用负载均衡,比如nginx

用缓存数据库,把热点数据get到缓存中,redis,ES

善于使用连接池。面试题整理好了,关注公众号后端面试那些事,回复:2022面经,即可获取

业务层面:加入交互,排队等待

怎么实现令牌桶限流?

首先,是微服务项目,创建一个gateway服务,一个测试服务

测试的时候通过网关端口访问测试服务的路径

1.父项目的依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<!--声明SpringBoot的依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

2.在gateway服务里面添加相关依赖

 <!-- 网关依赖 -->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
      <version>2.2.5.RELEASE</version>
  </dependency>

  <!--redis gateway令牌桶依赖 监控依赖-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>

  <!—redis令牌桶依赖-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
      <version>2.1.2.RELEASE</version>
  </dependency>

3.在gateway服务里面的启动类添加一段代码

/***
 * IP限流
 * @return
 */
@Bean(name="ipKeyResolver")
public KeyResolver userKeyResolver() {
    return new KeyResolver() {
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            //获取远程客户端IP
            String hostName = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
            System.out.println("hostName:"+hostName);
            return Mono.just(hostName);
        }
    };
}

4. 在gateway服务里面的application.yml里面添加配置

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        - id: gateway1
          uri: http://localhost:8080
          predicates:
            - Path=/abc/test/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter #请求数限流 名字不能随便写 ,使用默认的facatory
              args:
                key-resolver: "#{@ipKeyResolver}" 
                redis-rate-limiter.replenishRate: 1 #是你希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶填充的速率
                redis-rate-limiter.burstCapacity: 3 #是指令牌桶的容量,允许在一秒钟内完成的最大请求数,将此值设置为零将阻止所有请求


  application:
    name: gateway-web
  #Redis配置
  redis:
    host: 127.0.0.1
    port: 6379

server:
  port: 8001
management:
  endpoint:
    gateway:
      enabled: true
    web:
      exposure:
        include: true

5. 在测试服务

@RestController
@RequestMapping("test")
public class TestqController {

    @GetMapping("getTest")
    public String getTest(){
        return "成功了!!!!";
    }
}

使用postman测试或者网页上测试或者jmeter测试

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值