在分布式架构中,当某个服务单元发生故障之后,通过断路由器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
春云Hystrix针对上述问题实现了断路由器,线程隔离等一系列服务保护功能。它是基于Netflix Hystrix实现,该框架的目标在于通过控制那些访问远程系统,服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
Hystrix具备服务降级,服务熔断,线程和信号隔离,请求缓存,请求合并以及服务监控等强大功能。
构建一个如下架构图的服务调用关系
包cn.sh.ribbon.service;
进口com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
进口org.slf4j.Logger;
进口org.slf4j.LoggerFactory;
进口org.springframework.beans.factory.annotation.Autowired;
进口org.springframework.stereotype.Service;
进口org.springframework.web.client.RestTemplate;/* *
* @author sh
*/@ service
公开课HelloService {
私有静态最终日志记录器=LoggerFactory.getLogger (HelloService.class);
@ autowired
私人创建RestTemplate创建RestTemplate;/* *
*使用@HystrixCommand注解指定回调方法
* @param名字
* @return
*/@HystrixCommand (fallbackMethod=皉ibbonHelloFallback commandKey=癶elloKey”)
公共ribbonHello字符串(字符串名称){
长开始=System.currentTimeMillis ();
字符串的结果=restTemplate.getForObject (" http://HELLO-SERVICE/hello& # 63; name=" +名字,String.class);
长债=System.currentTimeMillis ();
logger.info(“花时间:”+(结束-开始));
返回结果;
}
公共字符串ribbonHelloFallback () {
返回“你好,我是回退”;
}
}
<强>改造服务提供者强>
改造hello-service模块中的HelloService.java,如下:
包cn.sh.hello.service; 进口org.slf4j.Logger; 进口org.slf4j.LoggerFactory; 进口org.springframework.stereotype.Service; 进口java.util.Random;/* * * @author sh */@ service 公开课HelloService { 私有静态最终日志记录器=LoggerFactory.getLogger (HelloService.class); 你好公共字符串(字符串名称)抛出InterruptedException { int sleepTime=new随机().nextInt (3000); logger.info (“sleepTime:“+ sleepTime); thread . sleep (sleepTime); 返回“你好,”+名称; } }
在服务提供者的改造中,我们会让方法阻塞几秒中返回内容,由于Hystrix默认的超时时间为2000毫秒,在这里产生0 - 3000的随机数可以让处理过程有一定概率触发断路由器。
下面根据工作流程图,我们来分析一下Hystrix是如何工作的。
<强>第1步创建HystrixCommand或HystrixObservableCommand对象强>
首先,构建一个HystrixCommand或HystrixObservableCommand对象,用来表示对依赖服务的操作请求,同时传递所有需要的参数。这两个对象都采用了命令模式来实现对服务调用操作的封装,但是这两个对象分别针对不同的应用场景。
HystrixCommand:用在依赖的服务返回单个操作结果的时候HystrixObservableCommand:用在依赖的服务返回多个操作结果的时候