微服务容灾组件:与 Feign 的结合使用
在介绍 feign 与 Hystrix 的结合之前,介绍一下雪崩的概念。
服务雪崩效应的定义很简单,是一种因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。
服务雪崩效应的产生一般有三个流程,服务提供者不可用 -> 重试加大流量 -> 服务调用者不可用
服务提供者不可用的出现的原因有很多,可能是因为服务器的宕机或者网络故障,也可能是因为程序存在的Bug,也有可能是大量的请求导致服务提供者的资源受限无法及时响应,还有可能是因为缓存击穿造成服务提供者超负荷运行等等,毕竟没有人能保证软件的完全正确性。
最后是服务调用者因为服务提供者的不能用导致了自身的崩溃。当服务调用者使用同步调用的时候,大量的等待线程将会耗尽线程池中的资源,最终导致服务调用者的宕机,无法响应用户的请求,服务雪崩效应就此发生了。
接下来我们学习 Feign与Hystrix 的结合使用。
Feign与Hystrix
使用Feign
需要添加相关依赖,在上一篇的基础上添加以下依赖:
<dependency>// openfegin的相关依赖
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Feign
是自带Hystrix,但是默认没有打开,在application.yml
中添加以下配置:
feign:
hystrix:
enabled: true
开启Fegin
,添加@EnableFeignClients
注解。
@SpringBootApplication
@EnableCircuitBreaker
@EnableFeignClients
@EnableDiscoveryClient
public class Chapter6HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(Chapter6HystrixApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
添加FeginClient
接口,调用feign-service
服务,同时指定失败回滚类为InstanceClientFallBack
。
@FeignClient(value = "feign-service", fallback = InstanceClientFallBack.class)
public interface InstanceClient {
@RequestMapping(value = "/feign-service/instance/{serviceId}", method = RequestMethod.GET)
public Instance getInstanceByServiceId(@PathVariable("serviceId") String serviceId);
}
继承InstanceClient
,提供相关的回滚方法。
@Component
public class InstanceClientFallBack implements InstanceClient {
private static Logger logger = LoggerFactory.getLogger(InstanceClientFallBack.class);
@Override
public Instance getInstanceByServiceId(String serviceId) {
logger.info("Can not get Instance by serviceId {}", serviceId);
return new Instance("error", "error", 0);
}
}
在InstanceService
添加相关的服务:
@Autowired
InstanceClient instanceClient;
public Instance getInstanceByServiceIdWithFeign(String serviceId){
Instance instance = instanceClient.getInstanceByServiceId(serviceId);
return instance;
}
在InstanceController
中添加相关的查看接口:
@RequestMapping(value = "feign/{serviceId}", method = RequestMethod.GET)
public Instance getInstanceByServiceIdWithFeign(@PathVariable("serviceId") String serviceId){
logger.info("Get Instance by serviceId {}", serviceId);
return instanceService.getInstanceByServiceIdWithFeign(serviceId);
}
依次启动eureka-server
、feign-service
以及本服务。
访问http://localhost:8876/instance/feign/my-application
接口。
{"serviceId":"my-application","host":"localhost","port":8080}
访问成功执行,返回预期的结果。
关闭feign-service
,再次访问http://localhost:8876/instance/feign/my-application
接口。
{"serviceId":"error","host":"error","port":0}
这说明Feign
中的失败回滚发挥了作用。
小结
容灾是为了发生故障时尽可能的减少损失。在服务提供者不可用发生之后,用户可能无法忍受长时间的等待,不断地发送相同的请求,服务调用者重新调用服务提供者,同时服务提供者中可能存在对异常的重试机制,这些都会加大对服务提供者的请求流量。然而此时的服务提供者已经是一艘破船,它也无能无力,无法返回有效的结果。
通过引入依赖,开启 FeginClient 的容灾功能,遇到服务不可用,可以及时失败回滚。
- 点赞
- 收藏
- 关注作者
评论(0)