首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从限流到熔断,彻底搞懂微服务雪崩的连锁反应

从限流到熔断,彻底搞懂微服务雪崩的连锁反应

原创
作者头像
叫我阿柒啊
发布2025-05-09 18:03:42
发布2025-05-09 18:03:42
5120
举报

前言

作为后端开发或者系统架构师,我们经常会听到一个词:服务雪崩。那什么是服务雪崩?假设你要点外卖,结果美团挂了,于是你打开饿了么,它人也突然变得很多变慢了,因为大家都涌过去了,接着你又去点百度地图导航,发现外卖小哥也用这个,系统也卡了,最后连微信支付都变得卡顿,这就是一种现实生活的雪崩。

在微服务架构中,一个服务往往依赖多个其他服务。如果某一个服务出问题没及时处理,请求会堆积、超时、失败、重试、传导到其它服务,最终导致整个系统都挂掉,这就是传说中的服务雪崩效应

服务雪崩

服务雪崩原因

我们来看看雪崩最常见的发生原因:

  1. 某个服务挂了,大家还在拼命访问它:比如用户服务挂了,但是订单服务、支付服务都还在调它,结果线程越占越多,资源越来越少,最后所有服务都挂掉。
  2. 某个服务变慢,导致请求堆积:每个调用环节响应时间变长了,也能把请求卡在中间,前后都被拖慢。
  3. 重试机制胡合理:为了防止因为短暂网络问题导致的服务调用失败,通常会加自动重试。但是失败了还反复调,只会让原本就扛不住的服务雪上加霜。

解决服务雪崩

那么,我们需要从哪些方面预防和解决服务雪崩的问题呢。

1. 超时控制

一个服务调用另一个服务,如果不设置超时时间,那调用就会一直等下去,占着线程不放,最终导致服务器的线程耗光,CPU繁忙,最后服务。

在调用其他服务时,比如用 HttpClient、Feign、Dubbo 时,要设置合理的超时时。

代码语言:java
复制
// Feign 设置超时
@Configuration
public class FeignConfig {
    @Bean
    public Request.Options options() {
        return new Request.Options(3000, 5000); // 连接超时3s,响应超时5s
    }
}
2. 限流

限流就是控制单位时间内最多允许多少请求进入。如果不做限流,一旦高并发来了,服务就直接崩溃。

常见限流方式:

  1. 令牌桶(Token Bucket):按速率发放“通行证”,没票进不来。
  2. 漏桶(Leaky Bucket):请求像水一样漏出来,处理不过来就丢弃。
  3. 固定窗口/滑动窗口算法:固定时间内处理固定数量请求。

常见工具

  1. Sentinel(阿里开源)
  2. Guava RateLimiter
  3. nginx自带限流模块
3. 熔断

服务B调用服务C,如果发现服务C响应时间太长或失败率太高,就断开连接,不再继续请求它,直接返回错误或者降级数据,就像家里电路短路了,为了安全会跳闸.

常用工具:

  1. Resilience4j(替代 Hystrix)
  2. Spring Cloud CircuitBreaker
  3. Sentinel 熔断模块

熔断的三种状态:

  1. Closed(闭合):正常状态,请求照常发。
  2. Open(打开):熔断中,拒绝请求。
  3. Half-Open(半开):探测状态,允许部分请求尝试,看服务是否恢复。

4. 降级

熔断之后要有备选方案,比如返回缓存数据、提示稍后再试等),不能什么都不返回,例如:

代码语言:java
复制
// 用Feign + Resilience4j示例
@FeignClient(name = "order-service", fallback = OrderFallback.class)
public interface OrderClient {
    @GetMapping("/order")
    String getOrder();
}

@Component
public class OrderFallback implements OrderClient {
    @Override
    public String getOrder() {
        return "服务繁忙,请稍后再试!";
    }
}
5. 隔离

在程序设计的时候实现服务隔离,避免一个服务的问题影响到其他服务。

  1. 线程池隔离:每个服务用自己的线程池,比如A服务的线程池爆了,B服务还能正常跑。
  2. 信号量隔离:限制最大并发数,多的请求直接失败或排队。
代码语言:java
复制
@Bean
public ThreadPoolExecutor myExecutor() {
    return new ThreadPoolExecutor(
        10, 50, 60, TimeUnit.SECONDS,
        new ArrayBlockingQueue<>(100),
        new ThreadPoolExecutor.AbortPolicy()
    );
}
6. 服务重启保护

当要重启某个服务时,不能立马就停掉,而是要先通知注册中心下线,在处理完当前请求之后才可以真正关闭。否则,刚好处理中的请求就被断掉了,调用服务触发了重试机制,形成连锁反应。

结语

通过本篇文章,我们学习了服务雪崩的常见原因,并从超时控制、限流、熔断到降级和隔离学习了常见的解决方案,只有提前做好防护,才能在高并发或异常情况下稳如老狗,避免线上系统大面积崩溃。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 服务雪崩
    • 服务雪崩原因
    • 解决服务雪崩
      • 1. 超时控制
      • 2. 限流
      • 3. 熔断
    • 4. 降级
      • 5. 隔离
      • 6. 服务重启保护
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档