
作为后端开发或者系统架构师,我们经常会听到一个词:服务雪崩。那什么是服务雪崩?假设你要点外卖,结果美团挂了,于是你打开饿了么,它人也突然变得很多变慢了,因为大家都涌过去了,接着你又去点百度地图导航,发现外卖小哥也用这个,系统也卡了,最后连微信支付都变得卡顿,这就是一种现实生活的雪崩。
在微服务架构中,一个服务往往依赖多个其他服务。如果某一个服务出问题没及时处理,请求会堆积、超时、失败、重试、传导到其它服务,最终导致整个系统都挂掉,这就是传说中的服务雪崩效应
我们来看看雪崩最常见的发生原因:
那么,我们需要从哪些方面预防和解决服务雪崩的问题呢。
一个服务调用另一个服务,如果不设置超时时间,那调用就会一直等下去,占着线程不放,最终导致服务器的线程耗光,CPU繁忙,最后服务。
在调用其他服务时,比如用 HttpClient、Feign、Dubbo 时,要设置合理的超时时。
// Feign 设置超时
@Configuration
public class FeignConfig {
@Bean
public Request.Options options() {
return new Request.Options(3000, 5000); // 连接超时3s,响应超时5s
}
}限流就是控制单位时间内最多允许多少请求进入。如果不做限流,一旦高并发来了,服务就直接崩溃。
常见限流方式:
常见工具:
服务B调用服务C,如果发现服务C响应时间太长或失败率太高,就断开连接,不再继续请求它,直接返回错误或者降级数据,就像家里电路短路了,为了安全会跳闸.
常用工具:
熔断的三种状态:
熔断之后要有备选方案,比如返回缓存数据、提示稍后再试等),不能什么都不返回,例如:
// 用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 "服务繁忙,请稍后再试!";
}
}在程序设计的时候实现服务隔离,避免一个服务的问题影响到其他服务。
@Bean
public ThreadPoolExecutor myExecutor() {
return new ThreadPoolExecutor(
10, 50, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadPoolExecutor.AbortPolicy()
);
}当要重启某个服务时,不能立马就停掉,而是要先通知注册中心下线,在处理完当前请求之后才可以真正关闭。否则,刚好处理中的请求就被断掉了,调用服务触发了重试机制,形成连锁反应。
通过本篇文章,我们学习了服务雪崩的常见原因,并从超时控制、限流、熔断到降级和隔离学习了常见的解决方案,只有提前做好防护,才能在高并发或异常情况下稳如老狗,避免线上系统大面积崩溃。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。