虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。
不管是线程隔离还是熔断降级,都是对客户端(调用方)的保护。
Feign整合Sentinel
SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合Feign和Sentinel。
1.修改OrderService的application.yml文件,开启Feign的Sentinel功能
# 开启feign对sentinel的支持
feign: sentinel: enabled: true
2.给FeignClient编写失败后的降级逻辑
方式一:FallbackClass,无法对远程调用的异常做处理
方式二:FallbackFactory,可以对远程调用的异常做处理,我们选择这种
步骤一:在feing-api项目中定义类,实现FallbackFactory:
@Slf4j public class UserClientFallbackFactory implements FallbackFactory<UserClient> { @Override public UserClient create(Throwable throwable) { // 创建UserClient接口实现类,实现其中的方法,编写失败降级的处理逻辑
return new UserClient() { @Override public User findById(Long id) { // 记录异常信息
log.error("查询用户异常", throwable); // 根据业务需求返回默认的数据,这里是空用户
return new User(); } }; } }
步骤二:在feing-api项目中的DefaultFeignConfiguration类中将UserClientFallbackFactory注册为一个Bean:
public class DefaultFeignConfiguration { @Bean public UserClientFallbackFactory userClientFallbackFactory(){ return new UserClientFallbackFactory(); } }
步骤三:在feing-api项目中的UserClient接口中使用UserClientFallbackFactory:
@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class) public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
总结
Sentinel支持的雪崩解决方案:
线程隔离(仓壁模式)
降级熔断