一、常用的限流算法 1.固定窗口计数器(计数器算法) 2 滑动窗口计数器算法 3. 漏桶算法 4 令牌桶算法(`常用`) Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法 二、 分布式限流 1、网关层(Nginx、Openresty、Spring Cloud Gateway等)流量限制 nginx限流 Spring Cloud Gateway 有两种方式来配置限流 2、中间件限流 Redis Sentinel ### 服务限流的核心知识点详解 #### 一、常用的限流算法 在处理高并发场景时,服务限流是一项非常重要的技术,它可以帮助系统更好地控制访问频率,避免资源被过度消耗,确保系统的稳定运行。 ##### 1. 固定窗口计数器(计数器算法) **概念解释**:固定窗口计数器算法是一种基于时间窗口的简单限流算法。它将时间分割成连续的固定长度的时间窗口,在每个窗口内统计请求的数量。一旦请求的数量超过预设的阈值,该窗口内的后续请求就会被拒绝。 **工作原理**: - 将时间划分为多个相同大小的窗口。 - 在每个窗口内,每当接收到一次新的请求时,计数器就增加1。 - 如果计数器的值超过了限定的最大值,那么该窗口内的剩余请求都将被拒绝。 - 当时间进入下一个窗口时,计数器会被重置。 **优点**:实现简单,易于理解和维护。 **缺点**:可能导致瞬时的过载。例如,在两个窗口的交界处可能会出现瞬间的流量峰值,导致实际的请求量超过设定的阈值。 **示例代码**: ```java public class FixedWindowCounter { private int count = 0; private long windowStart; public synchronized boolean allowRequest(int maxRequests) { long now = System.currentTimeMillis(); if (now - windowStart >= 1000) { // 每秒为一个窗口 count = 0; windowStart = now; } if (count >= maxRequests) { return false; } count++; return true; } } ``` ##### 2. 滑动窗口计数器算法 **概念解释**:滑动窗口计数器算法是对固定窗口计数器算法的一种改进。它同样将时间划分为多个窗口,但是这些窗口是连续重叠的,而不是完全独立的。 **工作原理**: - 将时间窗口划分为更小的时间段(称为子窗口)。 - 每个子窗口内的请求计数被保存起来。 - 当新请求到来时,计算最近一段时间内的所有子窗口请求计数之和。 - 如果总和超过了限制,那么新的请求将被拒绝。 **优点**:相比固定窗口算法,滑动窗口算法更加平滑地处理了请求的瞬时高峰,避免了固定窗口算法可能出现的瞬间过载问题。 **缺点**:实现相对复杂,需要维护更多的数据结构。 **示例代码**: ```java public class SlidingWindowCounter { private final Queue<Long> requests = new LinkedList<>(); private final int maxRequestsPerSecond; public SlidingWindowCounter(int maxRequestsPerSecond) { this.maxRequestsPerSecond = maxRequestsPerSecond; } public synchronized boolean allowRequest() { long now = System.currentTimeMillis(); while (!requests.isEmpty() && now - requests.peek() > 1000) { requests.poll(); } if (requests.size() >= maxRequestsPerSecond) { return false; } requests.offer(now); return true; } } ``` ##### 3. 漏桶算法 **概念解释**:漏桶算法通过将请求视为水流,将系统视为一个有固定容量的桶,当请求到达时,桶以一定的速度处理请求。如果桶满了,多余的请求会被丢弃。 **工作原理**: - 请求被视为水滴进入桶中。 - 桶以恒定的速度“漏水”。 - 如果桶满了,额外的水滴会被丢弃。 **优点**:简单易懂,能有效防止突发流量。 **缺点**:对于突发流量的处理不够灵活。 **示例代码**: ```java public class LeakyBucket { private final Queue<Long> queue = new LinkedList<>(); private final long capacity; private final long rate; public LeakyBucket(long capacity, long rate) { this.capacity = capacity; this.rate = rate; // 每秒处理请求的数量 } public synchronized boolean allowRequest() { long now = System.currentTimeMillis(); while (!queue.isEmpty() && now - queue.peek() > 1000 / rate) { queue.poll(); } if (queue.size() >= capacity) { return false; } queue.offer(now); return true; } } ``` ##### 4. 令牌桶算法 **概念解释**:令牌桶算法是一种更先进的限流策略,它不仅能够限制流量,还能平滑突发流量。该算法通过不断向一个令牌桶中添加令牌,然后让请求从桶中获取令牌来实现。 **工作原理**: - 令牌以恒定的速率生成,并存储在令牌桶中。 - 请求到达时,需要从桶中获取令牌才能继续处理。 - 如果桶中没有足够的令牌,那么请求将被拒绝。 **优点**:既能处理突发流量,又能保持平均流量的稳定性。 **缺点**:实现相对复杂。 **示例代码**: ```java import com.google.common.util.concurrent.RateLimiter; public class TokenBucketExample { private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10个令牌 public boolean allowRequest() { return rateLimiter.tryAcquire(); } } ``` #### 二、分布式限流 在分布式系统中,单机限流不足以应对大规模的并发请求,需要实现分布式限流。 ##### 1. 网关层限流 - **Nginx限流**:可以通过`ngx_http_limit_conn_module`模块限制连接数,通过`ngx_http_limit_req_module`模块限制请求速率。 - **Spring Cloud Gateway**:支持多种方式实现限流,如: - 使用`RedisRateLimiter`配合`@RateLimiter`注解。 - 使用自定义的过滤器实现限流逻辑。 **示例配置**: ```yaml spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "*" allowedMethods: "*" allowedHeaders: "*" routes: - id: user_service uri: lb://user-service predicates: - Path=/api/users/** filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 redis-rate-limiter.burstCapacity: 20 ``` ##### 2. 中间件限流 - **Redis**:利用Redis作为共享状态存储,实现跨节点的限流。 - **Sentinel**:阿里巴巴开源的分布式流量控制组件,可以实现热点规则、流控规则等多种限流策略。 **示例配置**: ```java // 使用Sentinel实现限流 import com.alibaba.csp.sentinel.annotation.SentinelResource; @RestController public class UserController { @SentinelResource(value = "getUser", fallback = "handleException") public String getUser(@RequestParam String id) { // ...业务逻辑... return "User: " + id; } public String handleException(String id) { return "Error: User not found: " + id; } } ``` 服务限流是高并发系统设计中的一项关键任务。不同的限流算法有着各自的特点和应用场景,选择合适的算法对于系统的稳定性和性能至关重要。同时,在分布式环境下,还需要结合网关层和中间件来实现更为高效的限流机制。
剩余6页未读,继续阅读
- 粉丝: 6238
- 资源: 81
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助