本文目录导读:

在Java分布式系统中,“降载”(降级与限流)和“削峰填谷”是保障系统稳定性的核心手段,下面从策略层面和代码实现层面系统梳理一下常用的降载方案。
核心策略分层
限流(Rate Limiting)
- 目的:控制进入系统的请求速率,防止流量冲垮系统。
- 常用算法:
- 计数器(固定窗口):简单但存在临界突变问题。
- 滑动窗口:解决固定窗口的突发问题。
- 漏桶(Leaky Bucket):平滑流量,强制固定速率。
- 令牌桶(Token Bucket):允许一定突发,更常用(如 Guava RateLimiter、Sentinel)。
- 粒度:单机限流(本地内存) vs 分布式限流(Redis + Lua)。
降级(Degradation)
- 目的:当系统压力过大或依赖服务不可用时,主动舍弃非核心功能,保证核心功能可用。
- 常见手段:
- 返回默认值/缓存值:如商品详情页当推荐服务失败时,展示空推荐或缓存推荐。
- 静态化/缓存兜底:直接返回静态页面或本地缓存。
- 熔断(Circuit Breaker):统计调用失败率,达到阈值直接拒绝调用(Hystrix、Resilience4j、Sentinel)。
- 系统级降级:关闭部分非关键线程池、禁止写操作、只读模式。
削峰填谷
- 目的:将瞬间高峰流量平缓地分摊到一段时间内处理,防止系统过载。
- 手段:
- 消息队列(MQ):请求先入队列,下游按能力消费(Kafka、RocketMQ、RabbitMQ)。
- 异步处理:立即返回“处理中”,后台慢慢跑。
- 缓冲区:如 Netty 的写缓冲区、内存队列 + 批量 flush。
常用开源组件落地
| 组件 | 功能 | 适用场景 |
|---|---|---|
| Sentinel | 限流、熔断、降级、热点参数限流、系统自适应保护 | 微服务架构,功能最全面,支持实时监控 |
| Hystrix (已维护模式) | 熔断、隔离、降级 | 老项目还在用,适合线程池隔离场景 |
| Resilience4j | 轻量级熔断、限流、重试、隔离 | 响应式编程友好,与 Spring Cloud Gateway 配合好 |
| Guava RateLimiter | 单机令牌桶限流 | 简单单机场景,不需要分布式协调 |
| Redisson RRateLimiter | 分布式令牌桶(基于Redis) | 多实例统一限流 |
分布式限流落地示例
基于 Redis + Lua 的滑动窗口限流(纯手写)
-- keys[1] = 限流key
-- ARGV[1] = 窗口大小(秒)
-- ARGV[2] = 最大请求数
local key = KEYS[1]
local window = tonumber(ARGV[1])
local maxRequests = tonumber(ARGV[2])
local now = redis.call('TIME')[1] -- 获取redis时间(秒)
redis.call('ZADD', key, now, now)
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
local count = redis.call('ZCARD', key)
redis.call('EXPIRE', key, window)
return count <= maxRequests
基于 Sentinel 的注解式限流(推荐)
@SentinelResource(value = "queryOrder", blockHandler = "blockHandlerForQuery")
public Order queryOrder(String id) {
// 正常业务逻辑
}
public Order blockHandlerForQuery(String id, BlockException ex) {
// 降级逻辑:返回缓存数据或错误提示
return new Order("FALLBACK", "系统繁忙,请稍后重试");
}
流量控制规则(控制台/代码配置):
{
"resource": "queryOrder",
"count": 100, // QPS 阈值
"grade": 1, // 0=线程数, 1=QPS
"controlBehavior": 2 // 0=快速失败, 1=Warm Up, 2=排队等待
}
降级与熔断实战
微服务内部降级(Feign + Sentinel)
@FeignClient(name = "product-service", fallback = ProductFallback.class)
public interface ProductClient {
@GetMapping("/product/{id}")
Product getProduct(@PathVariable("id") Long id);
}
@Component
public class ProductFallback implements ProductClient {
@Override
public Product getProduct(Long id) {
// 返回降级数据
return new Product(id, "降级商品信息", 0.0);
}
}
熔断器配置(Resilience4j)
resilience4j.circuitbreaker:
instances:
userService:
registerHealthIndicator: true
slidingWindowSize: 10 # 统计窗口大小(请求数)
minimumNumberOfCalls: 5 # 最小请求数(低于此值不触发熔断)
failureRateThreshold: 50 # 失败率阈值(%)
waitDurationInOpenState: 10s # 熔断后等待时间
permittedNumberOfCallsInHalfOpenState: 3 # 半开状态下允许的请求数
削峰填谷-消息队列版
利用 MQ 做流量蓄水池
// 生产者:接收请求后直接发消息
public void createOrder(OrderRequest req) {
kafkaTemplate.send("order-topic", req);
return "订单已提交,处理中";
}
// 消费者:按自身能力消费(可通过配置消费线程数 + 流量控制)
@KafkaListener(topics = "order-topic", concurrency = "5")
public void processOrder(ConsumerRecord<String, OrderRequest> record) {
// 这里可以叠加本地限流
orderService.create(record.value());
}
配合批量消费:
spring.kafka.listener: type: BATCH batch-size: 100 # 每批最多100条 poll-timeout: 1000ms # 等待时间
系统级自适应降载(进阶)
基于 CPU/内存负载的限流(Sentinel 系统自适应保护)
// 配置:当系统负载 > 80% 时自动拒绝新请求 SystemRule rule = new SystemRule(); rule.setHighestSystemLoad(0.8); // CPU 负载 rule.setAvgRt(1000); // 平均响应时间(ms) rule.setQps(10000); // 最大 QPS SystemRuleManager.loadRules(Collections.singletonList(rule));
线程池隔离降级(Hystrix 方式,推荐用 Sentinel 替代)
// 将不关键的服务放在独立的线程池中,线程池满时自动降级
@HystrixCommand(
groupKey = "recommendation",
commandKey = "getRecommendation",
threadPoolKey = "recommendation-pool",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "10"),
@HystrixProperty(name = "maxQueueSize", value = "50")
},
fallbackMethod = "getRecommendationFallback"
)
public List<Product> getRecommendation(String userId) {
return recommendationService.get(userId);
}
降载设计原则总结
| 原则 | 具体做法 |
|---|---|
| 快速失败 | 限流触及时直接返回 429(Too Many Requests),不占用资源 |
| 有损服务 | 核心功能保100%可用,非核心功能降级(如推荐、日志、统计) |
| 异步化 | 非实时请求丢 MQ,不要同步等待 |
| 削峰 | 利用 MQ 或本地缓冲队列,把瞬时压力平摊 |
| 兜底数据 | 所有依赖外部服务的地方都要有降级数据(默认值、缓存) |
| 监控告警 | 降载触发时要记录日志 + 推送告警,便于排查 |
推荐技术栈组合
Spring Cloud Gateway (网关层) —— Sentinel 限流 + 请求聚合
↓
微服务 A —— Sentinel (限流 + 熔断) + Resilience4j (重试)
↓
微服务 B —— 同 A,外加 MQ 削峰(RocketMQ/Kafka)
↓
数据库/缓存 —— 连接池限流、读写分离、缓存降级
一句话总结:降载的核心是 “放弃非核心,保护核心”,技术上通过 限流控制入口流量、降级处理异常依赖、MQ 削平流量尖峰 三招组合使用。
如果需要针对某个具体场景(如秒杀、大数据导入、实时推送)的降载方案,可以进一步细化讨论。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播