本文目录导读:

在Java中实现熔断限流,通常有三种主流方式:手动代码实现、使用开源框架(如Sentinel、Resilience4j)、以及依赖网关层(如Spring Cloud Gateway + Redis)。
以下是详细的实现方案,从简单到生产级应用。
限流实现(Rate Limiting)
限流的核心是控制访问频率,常见算法有:令牌桶、漏桶、滑动窗口。
使用 Guava RateLimiter(单机版/简单场景)
优点:代码简单,适合单机应用。 缺点:无法跨进程,不适合分布式。
import com.google.common.util.concurrent.RateLimiter;
public class RateLimiterDemo {
// 每秒生成10个令牌,即每秒最多允许10个请求
private static final RateLimiter rateLimiter = RateLimiter.create(10.0);
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
// 尝试获取令牌,若获取失败则阻塞直到获取到
double waitTime = rateLimiter.acquire();
System.out.println("请求" + i + "等待了" + waitTime + "秒");
// 业务逻辑
doBusiness();
}
}
private static void doBusiness() {
System.out.println("执行业务逻辑...");
}
}
使用 Redis + Lua 脚本(分布式限流)
原理:利用Redis的原子性操作,记录单位时间内的请求次数。
Lua 脚本(redis-rate-limiter.lua):
local key = KEYS[1] -- 限流的key
local limit = tonumber(ARGV[1]) -- 限制次数
local expire = tonumber(ARGV[2]) -- 时间窗口(秒)
local current = redis.call('INCR', key)
if current == 1 then
redis.call('EXPIRE', key, expire)
end
if current > limit then
return 0 -- 被限流
else
return 1 -- 允许通过
end
Java 调用代码:
import redis.clients.jedis.Jedis;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
public class RedisRateLimiter {
private final RedisTemplate<String, String> redisTemplate;
private final DefaultRedisScript<Long> script;
public RedisRateLimiter(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
this.script = new DefaultRedisScript<>();
this.script.setScriptText(getScriptContent()); // 加载上面Lua脚本
this.script.setResultType(Long.class);
}
public boolean tryAcquire(String key, int limit, int expireSeconds) {
Long result = redisTemplate.execute(script,
Collections.singletonList(key),
String.valueOf(limit),
String.valueOf(expireSeconds));
return result != null && result == 1L;
}
// 使用示例:限制 userId=123 在10秒内最多只能请求5次
// tryAcquire("limiter:user:123", 5, 10)
}
熔断实现(Circuit Breaker)
熔断是为了防止级联故障(雪崩),当服务异常率过高时,快速失败(打开电路),避免长时间等待。
手动实现(状态机)
状态:关闭(允许请求) → 打开(快速失败) → 半开(尝试恢复)
public class CircuitBreaker {
private volatile CircuitState state = CircuitState.CLOSED;
private final int failureThreshold; // 触发熔断的失败次数
private final long timeout; // 熔断后到半开的时间
private int failureCount = 0;
private long lastFailureTime;
public enum CircuitState {
CLOSED, // 关闭(正常)
OPEN, // 打开(熔断)
HALF_OPEN // 半开(尝试恢复)
}
public CircuitBreaker(int failureThreshold, long timeout) {
this.failureThreshold = failureThreshold;
this.timeout = timeout;
}
public synchronized boolean allowRequest() {
switch (state) {
case CLOSED:
return true;
case OPEN:
// 检查是否过了熔断时间,是则转为半开
if (System.currentTimeMillis() - lastFailureTime > timeout) {
state = CircuitState.HALF_OPEN;
return true;
}
return false;
case HALF_OPEN:
return true;
}
return false;
}
public synchronized void recordSuccess() {
if (state == CircuitState.HALF_OPEN) {
state = CircuitState.CLOSED;
failureCount = 0;
}
}
public synchronized void recordFailure() {
failureCount++;
lastFailureTime = System.currentTimeMillis();
if (failureCount >= failureThreshold) {
state = CircuitState.OPEN;
}
}
}
使用方式:
public class BusinessService {
private CircuitBreaker breaker = new CircuitBreaker(5, 10_000); // 5次失败,熔断10秒
public String call() {
if (!breaker.allowRequest()) {
throw new RuntimeException("Circuit breaker is open, request rejected");
}
try {
// 调用下游服务
String result = callDownstream();
breaker.recordSuccess();
return result;
} catch (Exception e) {
breaker.recordFailure();
throw e;
}
}
}
主流生产框架推荐
Sentinel(阿里开源的流量防卫兵)
特点:
- 支持实时监控
- 支持熔断降级、系统自适应保护
- 支持注解,配置灵活
引入依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
使用注解实现限流熔断:
@Service
public class OrderService {
// 限流:每秒最多允许20个请求
@SentinelResource(value = "createOrder",
blockHandler = "blockHandlerMethod",
fallback = "fallbackMethod")
public String createOrder(String userId) {
// 正常业务逻辑
return "Order created for " + userId;
}
// 限流后的处理
public String blockHandlerMethod(String userId, BlockException e) {
return "Too many requests, please try later.";
}
// 服务异常后的降级
public String fallbackMethod(String userId, Throwable e) {
return "Service unavailable, fallback.";
}
}
Resilience4j(Spring Cloud Circuit Breaker 默认实现)
特点:
- 轻量级,与Hystrix类似但更现代
- 功能模块化:熔断、重试、限流、隔离
引入依赖:
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>2.0.2</version>
</dependency>
yaml 配置:
resilience4j:
circuitbreaker:
instances:
userService:
registerHealthIndicator: true
slidingWindowSize: 10 # 滑动窗口大小
minimumNumberOfCalls: 5 # 最少请求次数
failureRateThreshold: 50 # 失败率阈值(百分比)
waitDurationInOpenState: 10s # 熔断保持时间
ratelimiter:
instances:
userService:
limitForPeriod: 10 # 周期内最大请求数
limitRefreshPeriod: 1s # 刷新周期
Java 使用:
@RestController
public class UserController {
@GetMapping("/user/{id}")
@CircuitBreaker(name = "userService", fallbackMethod = "userFallback")
@RateLimiter(name = "userService")
public String getUser(@PathVariable String id) {
// 调用下游服务
return restTemplate.getForObject("http://user-service/user/" + id, String.class);
}
public String userFallback(Exception e) {
return "Fallback: Service is unavailable.";
}
}
网关层限流(常用方案)
Spring Cloud Gateway + RequestRateLimiter
原理:基于Redis的令牌桶算法。
配置:
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@userKeyResolver}" # 限流key提取器
redis-rate-limiter.replenishRate: 10 # 令牌每秒填充数
redis-rate-limiter.burstCapacity: 20 # 最大令牌数
# 自定义 key-resolver
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}
总结与最佳实践
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 单机限流 | Guava RateLimiter | 简单,但无法分布式 |
| 分布式限流 | Redis + Lua | 性能好,适合多实例部署 |
| 熔断降级 | Resilience4j / Sentinel | 生产级,支持监控 |
| 网关限流 | Spring Cloud Gateway + Redis | 统一入口控制 |
| 复杂策略 | Sentinel | 支持热点限流、系统保护、集群流控 |
关键原则:
- 限流和熔断要配合使用:限流防止过载,熔断防止级联故障。
- 合理设置阈值:基于压测数据调整,避免误杀或失效。
- 降级处理:熔断时提供默认的 fallback 返回,避免前端白屏。
- 监控和告警:结合 Prometheus + Grafana 监控熔断/限流状态。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播