1 介绍
1.1 服务雪崩
多个微服务之间调用的时候,假设服务 A 调用服务 B 和服务 C,如果在这条链路上某个服务的调用响应时间过长或不可用,对服务 A 的调用就会占用越来越多的资源,进而导致其他服务不可用,引起系统崩溃,也就是“雪崩效应”。
1.2 Hystrix
Hystrix 是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix 能够保证在一个依赖出现问题的情况下,不会导致整体服务的失败,避免级联故障,以提高分布式系统的弹性。其有以下功能:
- 服务熔断
- 服务降级
- 服务限流
- 接近实时的监控
1.3 服务熔断
当微服务某链路的某个服务不可用或响应时间过长,会出现服务降级,进而熔断该节点的服务调用,快速返回错误的相应信息。当检测到该节点服务响应正常后则恢复调用的链路。
Hystrix 会监控微服务间的调用状况,当失败的调用到一定的阈值,一般是 5 秒内 20 次调用失败就会启动熔断机制。
2 整合 Hystrix
在服务消费者模块中添加如下信息:
2.1 pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.2 application.yml
Feign 是自带熔断器的,但默认是关闭的。需要在配置文件中配置打开它。
# 服务熔断
feign:
hystrix:
enabled: true
2.3 Service
创建实现 Feign 接口的类。
- Feign 接口实现类
/**
* 用户信息业务逻辑 Hystrix 策略
*/
@Service
public class UserInfoHystrixServiceImpl implements UserInfoService {
/**
* 解决 feign 的 getByName() 服务调用失败的策略
* @param username
* @return
*/
@Override
public UserInfo getByName(String username) {
// 自定义策略
UserInfo userInfo = new UserInfo();
userInfo.setUsername("网络延时,请稍后再试");
return userInfo;
}
}
- Feign 接口
/**
* 用户信息业务逻辑 Feign 接口
*/
@FeignClient(value = "springcloud-provider", path = "/users", configuration = FeignConfig.class, fallback = UserInfoHystrixServiceImpl.class)
public interface UserInfoService {
@RequestMapping(value = "/{username}")
UserInfo getByName(@PathVariable(value = "username") String username);
}
FeignConfig 配置类在 SpringCloud 负载均衡(Feign) 的自定义认证中。通过 fallback 指定调用失败的策略类。
2.4 启动类
只需要在启动类中添加 @EnableHystrix 。
@SpringBootApplication
@EnableEurekaClient // 表明自己是个 eureka 客户端,会自动注册到 eureka 服务端中
@EnableFeignClients(basePackages = {"com.pky.springcloud"})
@EnableHystrix // 启动 Hystrix
public class ConsumerHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerHystrixApplication.class, args);
}
}
2.4 启动测试
先启动服务消费者,关闭服务提供者。然后调用接口:
然后启动服务提供者,再次调用接口:
2.5 特别提醒
在开发过程中,发现无论服务是好是坏,调用接口时都直接返回了 fallback 的策略。此时需要坚持调用的服务名是否正确。
然后再检查是否在 Feign 配置类中实现了 RequestRequestInterceptor 做权限校验。如果是,则新建一个拦截器来实现 RequestRequestInterceptor,不要使用 Feign 配置类实现,只需要注入拦截器的 bean 即可,参考SpringCloud 负载均衡(Feign) 的自定义认证。
以上则完成了服务熔断。