Java分布式限流的方式 1. 简介 分布式限流是指在分布式系统中对请求进行限制,以控制系统的负载和保护系统的稳定性。在Java开发中,常用的分布式限流方式有:令牌桶算法、漏桶算法
Java分布式限流的方式
1. 简介
分布式限流是指在分布式系统中对请求进行限制,以控制系统的负载和保护系统的稳定性。在Java开发中,常用的分布式限流方式有:令牌桶算法、漏桶算法和计数器算法。本文将介绍这三种常见的分布式限流方式,并提供相应的代码实例。
2. 限流流程
下面是实现Java分布式限流的一般流程:
flowchart TD
A[获取请求] --> B[根据规则判断是否限流]
B --> |未限流| C[执行请求]
B --> |限流| D[返回限流提示]
3. 分布式限流实现方式
3.1 令牌桶算法
令牌桶算法是一种常见的限流算法。其原理是系统以恒定的速率往一个令牌桶中放入令牌,而处理请求前需要从令牌桶中获取令牌,如果获取不到令牌则表示限流。以下是令牌桶算法的Java实现示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class TokenBucket {
private final int MAX_TOKENS;
private final int tokensPerSecond;
private double tokens;
private long lastRefreshTime;
public TokenBucket(int tokensPerSecond) {
this.tokensPerSecond = tokensPerSecond;
this.MAX_TOKENS = tokensPerSecond;
this.tokens = MAX_TOKENS;
this.lastRefreshTime = System.currentTimeMillis();
}
public synchronized boolean allowRequest(int tokens) {
refresh();
if (tokens <= this.tokens) {
this.tokens -= tokens;
return true;
}
return false;
}
private synchronized void refresh() {
long currentTime = System.currentTimeMillis();
double elapsedTime = (currentTime - lastRefreshTime) / 1000.0;
double newTokens = elapsedTime * tokensPerSecond;
this.tokens = Math.min(this.tokens + newTokens, MAX_TOKENS);
this.lastRefreshTime = currentTime;
}
public static void main(String[] args) throws InterruptedException {
TokenBucket tokenBucket = new TokenBucket(10);
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 20; i++) {
executorService.submit(() -> {
try {
if (tokenBucket.allowRequest(1)) {
System.out.println("Request processed");
} else {
System.out.println("Request rejected");
}
} catch (Exception e) {
e.printStackTrace();
}
});
TimeUnit.MILLISECONDS.sleep(100);
}
executorService.shutdown();
}
}
在上述代码中,TokenBucket类实现了令牌桶算法。其中,allowRequest方法用于判断是否允许请求通过,refresh方法用于刷新桶中的令牌数量。在main方法中,模拟了20个请求,每个请求需要获取1个令牌,如果获取到令牌则表示请求通过,否则请求被拒绝。
3.2 漏桶算法
漏桶算法是另一种常见的限流算法。其原理是系统以恒定的速率处理请求,并将多余的请求放入一个漏桶中,如果漏桶已满则表示限流。以下是漏桶算法的Java实现示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class LeakyBucket {
private final int capacity;
private final int rate;
private int water;
private long lastLeakTime;
public LeakyBucket(int capacity, int rate) {
this.capacity = capacity;
this.rate = rate;
this.water = 0;
this.lastLeakTime = System.currentTimeMillis();
}
public synchronized boolean allowRequest() {
leak();
if (water < capacity) {
water++;
return true;
}
return false;
}
private synchronized void leak() {
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - lastLeakTime;
int leakedWater = (int) (elapsedTime / 1000.0 * rate);
water = Math.max(0, water - leakedWater);
lastLeakTime = currentTime;
}
public static void main(String[] args) throws InterruptedException {
LeakyBucket leakyBucket = new