什么是Hystrix?
在分布式环境中,不可避免地会有许多服务依赖项中的某些失败。
Hystrix是一个库,可通过添加等待时间容限和容错逻辑来帮助您控制
这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,
停止服务之间的级联故障并提供后备选项来实现此目的,
所有这些都可以提高系统的整体弹性。
Hystrix的作用是什么?
Hystrix旨在执行以下操作:
- 提供保护并控制通过第三方客户端库访问(通常是通过网络)的依赖项带来的延迟和失败。
- 停止复杂的分布式系统中的级联故障。
- 快速失败并快速恢复。
- 回退并在可能的情况下正常降级。
- 启用近乎实时的监视,警报和操作控制。
Hystrix如何实现?
-
资源隔离模式
在一个高度服务化的系统中,我们实现一个业务功能,可能需要依赖多个第三方服务,
如果第三方服务有出现不可用,这样导致我们业务服务线程就会阻塞等待。当大量的线程
进入阻塞等待,引发整个服务不可用,这种相当可怕。Hystrix提供Bulkheads(舱壁隔离模式)进行将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。
-
熔断器模式
熔断器模式是使用状态机进行状态切换控制,大致流程如下:
-
命令模式
Hystrix使用命令模式(继承HystrixCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback)。同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数。
-
观察者模式
Hystrix通过观察者模式对服务进行状态监听。每个任务都包含有一个对应的Metrics,所有Metrics都由一个ConcurrentHashMap来进行维护,Key是CommandKey.name()。在任务的不同阶段会往Metrics中写入不同的信息,Metrics会对统计到的历史信息进行统计汇总,供熔断器以及Dashboard监控时使用。
Ribbon + RestTemplate 使用Hystrix
复用之前Eureka注册的工程,修改EurekaClientConsumer工程相关内容。
pom.xml文件增加如下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</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!
Feign 使用Hystrix
复用之前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!
Hystrix监控面板
Ribbon + RestTemplate
修改EurekaClientConsumer工程相关内容。
pom.xml增加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
</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 共支持三种不同的监控方式:
- 默认的集群监控:通过 URL:http://turbine-hostname:port/turbine.stream 开启,实现对默认集群的监控。
- 指定的集群监控:通过 URL:http://turbine-hostname:port/turbine.stream?cluster=[clusterName] 开启,实现对 clusterName 集群的监控。
- 单体应用的监控: 通过 URL:http://hystrix-app:port/actuator/hystrix.stream 开启 ,实现对具体某个服务实例的监控。
页面上的另外两个参数:
- Delay:控制服务器上轮询监控信息的延迟时间,默认为 2000 毫秒,可以通过配置该属性来降低客户端的网络和 CPU 消耗。
- Title:该参数可以展示合适的标题。
我们输入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,
然后再刷新之前的界面,这时我们就可以看到统计的信息。
界面显示字段内容图解如下:
Feign
与上面除了端口号之外,其他内容一致,就不重复说明。
附录
Hystrix已经不再处于主动开发中,并且当前处于维护模式,但是不影响使用。
官网给的解释:
Hystrix(1.5.18版)足够稳定,可以满足Netflix现有应用程序的需求。
同时,我们的重点已转向对应用程序的实时性能做出反应的自适应性实现,
而不是预先配置的设置(例如,通过自适应并发限制)。对于像Hystrix
这样有意义的情况,我们打算继续将Hystrix用于现有应用程序,并为新的
内部项目利用诸如resilience4j之类的开放式活动项目。我们开始建议其
他人也这样做。
附录
源代码地址:https://gitee.com/LeeJunProject/spring_cloud_learning/tree/master/eureka/EurekaDemo
END
欢迎扫描下图关注公众号 IT李哥,公众号经常推送一些优质的技术文章