在分布式环境中,不可避免地会有许多服务依赖项中的某些失败。
Hystrix是一个库,可通过添加等待时间容限和容错逻辑来帮助您控制
这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,
停止服务之间的级联故障并提供后备选项来实现此目的,
所有这些都可以提高系统的整体弹性。
Hystrix旨在执行以下操作:
资源隔离模式
在一个高度服务化的系统中,我们实现一个业务功能,可能需要依赖多个第三方服务,
如果第三方服务有出现不可用,这样导致我们业务服务线程就会阻塞等待。当大量的线程
进入阻塞等待,引发整个服务不可用,这种相当可怕。
Hystrix提供Bulkheads(舱壁隔离模式)进行将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。
熔断器模式
熔断器模式是使用状态机进行状态切换控制,大致流程如下:
命令模式
Hystrix使用命令模式(继承HystrixCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback)。同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数。
观察者模式
Hystrix通过观察者模式对服务进行状态监听。每个任务都包含有一个对应的Metrics,所有Metrics都由一个ConcurrentHashMap来进行维护,Key是CommandKey.name()。在任务的不同阶段会往Metrics中写入不同的信息,Metrics会对统计到的历史信息进行统计汇总,供熔断器以及Dashboard监控时使用。
复用之前Eureka注册的工程,修改EurekaClientConsumer工程相关内容。
pom.xml文件增加如下依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
启动类增加@EnableHystrix注解,并且修改MessageController类增加
出错处理方法,最终MessageController类内容如下:
@RestController
public class MessageController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/show")
@HystrixCommand(fallbackMethod = "error")
public String showMessage(@RequestParam String name){
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("token", "IT_LiGe");
//producer 为提供的服务注入到eureka的名称
return (restTemplate.exchange("http://producer/get?name="+name,
HttpMethod.GET,new HttpEntity<String>(requestHeaders), String.class)).getBody();
}
public String error(String name) {
return name + "error!";
}
}
启动俩个提供服务工程,访问http://127.0.0.1:8600/show?name=IT_LiGe,显示如下:
Hi IT_LiGe ,I am from port:8001,token:IT_LiGe_Token
或者
Hi IT_LiGe ,I am from port:8002,token:IT_LiGe_Token
不启动俩个提供服务工程,访问http://127.0.0.1:8600/show?name=IT_LiGe,restTemplate发起请求出现错误,进入error方法,所以界面显示如下:
IT_LiGeerror!
复用之前Eureka注册的工程,修改EurekaClientFeign工程相关内容。
application.yal配置文件增加如下内容:
feign:
hystrix:
enabled: true
增加熔断回调类MessagesFeignFallback,内容如下:
@Component
public class MessagesFeignFallback implements MessagesFeignClient {
@Override
public String getName(String name) {
return name +"error";
}
}
进行修改使用@FeignClient注解的MessagesFeignClient类。最终类内容如下:
@FeignClient(name = "producer",fallback = MessagesFeignFallback.class)
public interface MessagesFeignClient {
@GetMapping(value = "/get")
String getName(@RequestParam(value = "name") String name);
}
如果需要使用错误内容进行判断可使用fallbackFactory参数。
例如:
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<MessagesFeignClient> {
@Override
public MessagesFeignClient create(Throwable arg0) {
// TODO Auto-generated method stub
return new MessagesFeignClient() {
@Override
public String getName(String name) {
return name +"error";
}
};
}
}
修改完成后,不启动俩个提供服务工程,访问http://127.0.0.1:8700/show?name=IT_LiGe请求出现错误,进入error方法,所以界面显示如下:
IT_LiGeerror!
修改EurekaClientConsumer工程相关内容。
pom.xml增加如下依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-netflix-hystrix-dashboardartifactId>
dependency>
启动类增加@EnableHystrixDashboard注解启动面板并且增加一个Servlet。最终完整代码如下:
@SpringBootApplication
@RibbonClient(name = "producer", configuration = MyRule.class)
@EnableHystrix
@EnableHystrixDashboard
public class EurekaClientConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientConsumerApplication.class, args);
}
@LoadBalanced //使用负载均衡机制
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/actuator/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
启动服务,访问http://127.0.0.1:8600/hystrix,显示Hystrix Dashboard。
通过 Hystrix Dashboard 主页面的文字介绍,我们可以知道,Hystrix Dashboard 共支持三种不同的监控方式:
页面上的另外两个参数:
我们输入http://127.0.0.1:8600/actuator/hystrix.stream,2000,IT_LiGe然后点击Monitor Stream。
我们发现界面显示Loading状态,这时候我们另外开一个界面访问http://127.0.0.1:8600/show?name=IT_LiGe,
然后再刷新之前的界面,这时我们就可以看到统计的信息。
界面显示字段内容图解如下:
与上面除了端口号之外,其他内容一致,就不重复说明。
Hystrix已经不再处于主动开发中,并且当前处于维护模式,但是不影响使用。
官网给的解释:
Hystrix(1.5.18版)足够稳定,可以满足Netflix现有应用程序的需求。
同时,我们的重点已转向对应用程序的实时性能做出反应的自适应性实现,
而不是预先配置的设置(例如,通过自适应并发限制)。对于像Hystrix
这样有意义的情况,我们打算继续将Hystrix用于现有应用程序,并为新的
内部项目利用诸如resilience4j之类的开放式活动项目。我们开始建议其
他人也这样做。
源代码地址:https://gitee.com/LeeJunProject/spring_cloud_learning/tree/master/eureka/EurekaDemo
欢迎扫描下图关注公众号 IT李哥,公众号经常推送一些优质的技术文章