1.为什么需要限流
1、大量正常用户高频访问导致服务器宕机
2、恶意用户高频访问导致服务器宕机
3、网页爬虫 ,对于这些情况我们需要对用户的访问进行限流访问
限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。
2.Gateway在哪里可以实现限流
2.1Gateway 相关概念
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway 作为Spring Cloud 生态系中的网关,目标是替代 Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。
- Route: 网关基本构建块,由一个 ID、一个目标 URI,一组 predicate 和一组 filter 定义,若 predicate 为真,则路由匹配。
- Predicate:输入类型是一个 ServerWebExchange,可以使用它来匹配来自 HTTP 请求的任何内容。
- Filter:Gateway 中分为两种 filter,一个是 Gateway Filter 一个是 Global Filter,filter 会对请求和响应进行修改处理。
2.2Gateway 工作流程
客户端访问 Gateway 网关,Gateway 中 Handler Mapping 对请求 URL 进行处理,如果网关处理程序映射确定请求与路由匹配,则处理完之后交给 web Handler,web handler 会被 filter 进行过滤。Filter 中分成两部分,以在代理请求发送之前和之后运行逻辑。其中前半部分代码是处理请求的代码,处理完成后调用真实被代理的服务,被代理的服务响应结果,结果会被 filter 中后半部分代码进行操作,操作完成后把结果返回给 web handler,再返回给 handler mapping,最终响应给客户端。
3.常见的限流方法
3.1计数器法
设置一个计数器 counter,每当一个请求过来的时候,counter+1,如果 counter 的值大于阈值且当前请求与第一个请求的间隔时间还在限定的时间之内,那么说明请求数过多;如果该请求与第一个
请求的间隔时间大于限定时间,且 counter 的值还在限流范围内,那么就重置 counter。
缺点:精度太低,无法处理临界问题。以 QPS = 100 举例,假设从第一个请求开始计时,每一个请求让计数器加一,当到达 100 以后,其他的请求都拒绝,如果一秒内前 200ms 请求数量到达了100,那么后面 800ms 中的所有请求都被拒绝了,导致出现“突刺现象”。
3.2滑动窗口法
将窗口更加细分,每个窗口都有自己的计数器,当总计算达到限定时,限流。这个滑动窗口只是将计算法变得更平滑而已。
缺点:治标不治本(仍会有突刺)。
假设时间周期为1min,将1min再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为75,第二个时间周期内,访问数量为100,超过100的访问则被限流掉了。