Semaphore 是单机轻量级限流工具,靠许可证数限制并发,不支持分布式协调;需全局唯一、同线程 acquire/release、设超时、保护真正耗资源操作,并可结合失败统计实现简易熔断。

用 Semaphore 控制高并发接口的访问配额,核心是靠“许可证数量”限制同一时刻能执行业务逻辑的请求数,属于单机轻量级限流手段。它不解决分布式问题,也不自动感知响应延迟,但胜在无依赖、易上手、可控性强——适合内部服务、定时任务或低 QPS 场景下的快速兜底。
明确信号量的作用边界
Semaphore 是 JVM 进程内同步工具,每个应用实例独享一套许可计数器。比如部署 3 台机器,每台设 new Semaphore(5),实际总并发上限就是 15,不是 5。它无法跨实例协调,也不能替代 Redis + Lua 或 Sentinel 等集中式方案。若你用的是云原生多副本架构,别指望靠它做全局限流。
正确初始化与线程安全使用
必须确保 Semaphore 实例全局唯一且生命周期与应用一致:
- Spring 环境下声明为 @Bean,避免每次 new 出新对象
- 禁止在异步线程(如 @Async、CompletableFuture)中 acquire 后,在主线程 release —— 必须同一线程配对
- 所有 acquire() 操作后,必须在 finally 块中调用 release(),否则异常中断会导致许可永久泄漏
- 优先选用 tryAcquire(long timeout, TimeUnit unit),设 100~300ms 超时,避免线程池被阻塞耗尽
把限流点放在真正需要保护的位置
不要简单地在 Controller 入口就 tryAcquire()。如果接口里包含鉴权、日志、参数校验等轻量逻辑,把这些放许可检查之前;只把真正消耗资源的操作(比如调第三方 API、写数据库、生成大文件)包进临界区。否则空转也占着许可,降低吞吐效率。
叠加失败统计实现简易熔断
Semaphore 不带熔断能力,但可以配合状态机模拟:
- 用 AtomicInteger 统计最近 60 秒内的失败请求数和总请求数
- 失败率超阈值(如 50%)且总请求数 ≥20,将开关置为 OPEN
- OPEN 状态下直接拒绝请求(跳过 tryAcquire),持续 30 秒后进入 HALF-OPEN,只放行 1~2 个试探请求
- 试探成功则恢复服务,失败则重置计时器
不复杂但容易忽略










