微服务-雪崩

雪崩问题

微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩

雪崩问题产生的原因?

  • 微服务相互调用,服务提供者出现故障或阻塞
  • 服务调用者没做好异常处理,导致自身故障
  • 调用链中的所有服务级联失败,导致整个集群故障

解决问题的思路有哪些?

尽量避免服务中出现问题或阻塞

  • 保证代码的健壮性
  • 保证网络畅通
  • 能应对较高的并发请求

解决方案

服务保护方案-请求限流

限制流量在服务可以处理的范围,避免因突发流量和故障

服务保护方案-线程隔离

控制业务可用的线程数量,将故障隔离在一定范围

服务保护方案-服务熔断

将异常比例过高的接口断开,拒绝所有请求,直接走fallback


Sentinel

搭建Sentinel

Sentinel: The Sentinel of Your Microservices

1
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.8.jar

sentinel是一个控制台应用程序,可以将其看作类似于Nacos的独立服务

整合Sentinel

1
2
3
4
5
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

簇点链路

簇点链路就是单机调用链路,是一次请求进入服务后经过的每一个被Sentinel监控的资源链。默认Sentinel会监控SpringMVC的每一个Endpoint(http接口)。限流、熔断都是针对于簇点链路的资源设置的。而资源名默认就是接口的请求路径。

请求方式前缀

Restful风格的API请求路径一般都相同,这会导致簇点资源名称重复,因此我们要修改配置,把请求方式+请求路径作为簇点资源名称

1
2
3
4
5
6
spring: 
cloud:
sentinel:
transport:
dashboard: localhost:8090
http-method-specify: true # 开启请求方式前缀

配置

在Sentinel中,可以针对于簇点链路进行限流/线程数量控制

当一个服务调用过慢,会将资源抢占耗尽,别的服务则无法正常调用,这个时候就应该配置线程隔离

将FeignClient作为Sentinel的簇点资源,让服务间调用也被sentinel监控

1
2
3
feign:
sentinel:
enabled: true # 开启sentinel支持

Fallback

基于FallbackFactory,编写FeignClient的fallback逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {
@Override
public ItemClient create(Throwable cause) {
return new ItemClient() {
@Override
public List<ItemApiDTO> queryItemByIds(Collection<Long> ids) {
log.error("查询商品失败", cause);
return CollUtils.emptyList();
}

@Override
public void deductStock(List<OrderDetailApiDTO> items) {
log.error("减少商品库存失败", cause);
throw new RuntimeException(cause);
}
};
}
}

在Feign的配置文件中,将fallback注册到bean中

1
2
3
4
@Bean
public ItemClientFallbackFactory itemClientFallbackFactory() {
return new ItemClientFallbackFactory();
}

在APIClient中,加载该bean

1
2
3
4
5
6
7
8
@FeignClient(value = "item-service", fallbackFactory = ItemClientFallbackFactory.class)
public interface ItemClient {
@GetMapping("/items")
List<ItemApiDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids );

@PutMapping("/items/stock/deduct")
public void deductStock(@RequestBody List<OrderDetailApiDTO> items);
}

Nacos提供注册服务 -> Feign调用服务 -> Sentinel进行流控或线程隔离抛出异常 -> fallback逻辑触发


配置熔断

熔断可以进一步增加性能优化,线程隔离和QPS可以保证服务可用,但仍然会尝试去请求,只有超时或线程不够才会失败

而熔断是设置一个规则,在尝试不行时直接先断开不用这个服务,过一段时间再尝试请求一下,如果还是失败,就继续断开



微服务-雪崩
http://blog.170827.xyz/2025/06/20/微服务-雪崩/
作者
XIAOBAI
发布于
2025年6月20日
许可协议