熔断降低

1.Hystrix

仪表盘:https://blog.csdn.net/weixin_62951914/article/details/145714593

详细使用教程:https://zhuanlan.zhihu.com/p/589484894

2.Sentinel

Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户提升服务的稳定性。

Sentinel 与 Hystrix 的主要区别?

  1. 设计理念:Hystrix 强调线程隔离和熔断,Sentinel 侧重流量控制与系统保护。
  2. 规则动态性:Sentinel 支持动态规则实时生效,Hystrix 需重启。
  3. 监控能力:Sentinel Dashboard 提供实时监控,Hystrix 依赖 Turbine。
  4. 扩展性:Sentinel 通过 Slot Chain 机制支持自定义扩展。

Hystrix 和 阿里的 sentinel:实现熔断的原理有什么不同的地方?

  1. 功能:Hystrix主要的指标是错误率(异常和超时时间),默认10s内错误率超过50%,就触发熔断。阻止后面请求继续调用。sentinel更加灵活,支持异常数量作为指标、支持限流。
  2. 配置:Hystrix不支持动态配置,sentinel支持。
  3. 熔断恢复机制:一样都支持关闭、打开和半开三种状态。当熔断超过一定时间后,会允许小量请求进入,如果继续触发指标阈值,则熔断。否则恢复。
  4. 实现原理:
    • Hystrix:使用线程池或者信号量实现服务间的隔离。默认使用线程池,可以实现线程级别的保护,但是会导致事务失效,可以改成信号量,但是无法实现超时的熔断。
    • sentinel:使用spring AOP实现。通过代理对象 与 sentinel内置的AOP类对所有注解的方法进行监控。采用了并发模型记录信息,性能非常好。

工作原理:Sentinel中所有资源(使用注解修饰的方法),都对应一个资源名称和Entry,每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain)。这些插槽有不同的职责

核心 Slot:

  • NodeSelectorSlot:创建资源对应的 ClusterNode。
  • ClusterBuilderSlot:维护资源与 ClusterNode 的映射。
  • StatisticSlot:统计实时指标(QPS、RT 等)。
  • AuthoritySlot:黑白名单控制。
  • SystemSlot:系统保护规则校验。
  • FlowSlot:流量控制规则校验。
  • DegradeSlot:熔断降级规则校验。

扩展机制:通过 SPI 加载自定义 Slot 插入责任链。

控制台的作用?

  1. 应用注册:客户端启动时向 Dashboard 注册(需配置 csp.sentinel.dashboard.server)。
  2. 心跳机制:客户端定时发送心跳保持连接。
  3. 规则拉取:Dashboard 通过 HTTP API 向客户端推送规则。
  4. 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。

集群控制实现原理

1.7版本新增集群管理。

  1. Token Server:负责全局流量统计和 Token 分配。可以选择单独运行,也可以嵌入到某个服务中。
  2. Token Client:应用节点向 Token Server 申请 Token。也就是我们启动的服务。
  3. 通信协议:使用 Netty 或 gRPC 进行 RPC 通信。
  4. 问题:Token Server 单点故障,需通过集群部署 + 心跳检测解决。 集群环境可以设置规则的持久化。通过 Nacos/ZK 推送规则到所有节点。

限流算法

Sentinel只提供的滑块窗口。将1s分为多个小窗口,每个小窗口内进行单独统计QPS、并发数量等指标。 除此之外的限流算法还有:时间窗口(计数器法)、漏桶法、令牌桶法等。

3.Resilience4j

Resilience4j 是一个轻量级、高性能的容错库,它专为 Java 8+ 与 Spring Boot 环境设计,可替代 Netflix Hystrix。

容错模式(Fault Tolerance Patterns):

  1. CircuitBreaker 熔断器:防止反复调用失败的服务
  2. RateLimiter 限流器:控制请求速率
  3. Retry 重试机制:失败后自动重试指定次数
  4. Bulkhead 舱壁隔离:限制并发请求数
  5. TimeLimiter 超时控制:为异步调用设置超时限制
  6. Cache 结果缓存。

4.限流

  1. 单机版:
    • Guava RateLimiter:令牌桶算法,无需外部依赖,轻量高效。仅支持单机,不支持异步非阻塞,功能单一。
    • Current-Limiting Starter:注解式配置。仅支持单机,不支持异步非阻塞,功能单一。
    • Resilience4j等微服务组件自带限流功能。核心是熔断功能,仅支持单机。
  2. 分布式:
    • Bucket4j:基于令牌桶算法的 Java 库,天生支持 JCache (Redis/Hazelcast)。
      1. 海量 Key 支持:利用 Redis 的 TTL 机制,哪怕有一亿个用户 ID 需要限流也能扛得住,且数据绝对精准。
      2. 极低开销:支持贪婪模式(Greedy)和纳秒级计算。
      3. 适用:API 计费、用户维度的精准限流、WAF 防火墙、SaaS 配额控制。
    • Redis + Lua 脚本
    • Sentinel。支持单机和集群模式,适用:微服务架构的系统保护、热点商品限流、网关层的大流量控制。
  3. 网关层级:Spring Cloud Gateway Filter支持全局、路径、Header 维度限流。
  4. 其他。JD-hotkey,它不是用来做全局限流的,而是用来探测的。适用:大促秒杀、微博热搜等瞬时流量极大的场景。
// 方案一:Guava RateLimiter (轻量极简版)
package com.example.common;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class RateLimitFilter implements Filter {
    // 每秒允许2个请求
    private final RateLimiter rateLimiter = RateLimiter.create(2.0);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (rateLimiter.tryAcquire()) {
            chain.doFilter(request, response);
        } else {
            ((HttpServletResponse) response).setStatus(429);
            response.getWriter().write("Too many requests");
        }
    }
}

// 方案二:注解式限流 (Current-Limiting Starter)
引入依赖:
<dependency>    
    <groupId>cn.yueshutong</groupId>    
    <artifactId>spring-boot-starter-current-limiting</artifactId>    
    <version>0.0.1.RELEASE</version>
</dependency>

@RestController
@RequestMapping("/api")
public class DemoController {    
    @GetMapping("/test")    
    @CurrentLimiter(QPS = 5) // 每秒最多5次    
    public String test() {        
        return "success";    
    }
}

5.选型

  1. 场景 A:
    • 我要做 API 计费 / 限制百万级用户调用必选:Bucket4j + Redis
    • 理由:Sentinel 处理不了海量 Key,LRU 会导致非热点用户限流失效。Bucket4j 配合 Redis 能够精准记录每一个用户的额度。
  2. 场景 B:
    • 我是 Spring Cloud 全家桶,怕服务雪崩首选:Sentinel
    • 理由:你需要的是熔断降级和系统自适应保护,Sentinel 的控制台和生态集成是最好的。 注:如果不用阿里系组件,Resilience4j 是标准替代品。
  3. 场景 C:
    • 我要做秒杀,怕 Redis 被打挂必选:JD-hotkey (+ Sentinel)
    • 理由:Bucket4j 依赖 Redis,如果热点太大会把 Redis 打死。JD-hotkey 能把热点拦截在本地内存中。
  4. 场景 D:
    • 我只是写个简单的爬虫或数据导入脚本首选:Guava
    • 理由:别搞复杂了,引入一个 Redis 没必要。

文章信息

张雪随笔
master
Homepage
Issues
Download

This Software is under the terms of The Unlicense.