在分布式的系统中,服务与服务之间有可能会存在依赖的情况,这时候就会出现一些问题,比方说服务A依赖于服务B,服务B又依赖于服务C,这个时候如果服务C出现了问题,那么久而久之服务B也会也会逐渐被服务C“拖垮”,进而,服务A也会逐渐出现问题(又称雪崩效应);所以我们迫切的需要一种“快速失败”的机制,告诉客户,我这个服务出现了问题,不再提供服务。
为了实现这种快速失败的机制,spring cloud提供了Hystrix(熔断器)这个工具。
那么...怎么实现咧?
这里依然沿袭前面的架构,sc01作为eureka服务器,sc07作为消费者(也即客户端),同时,新建sc08作为服务的提供者,我们在sc08中手动模拟一些错误:
导入hystrix相关的依赖:
<hystrix.version>1.5.12</hystrix.version>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>${hystrix.version}</version>
</dependency>
在启动类上标记注解@EnableCircuitBreaker,打开hystrix熔断器的功能。
在controller中添加一个方法,用于模拟一些异常情况:
@GetMapping("/getInfo")
@HystrixCommand(fallbackMethod = "hystrixFunction")
public Object get() {
Integer result=2/0;
return result;
}
这里是通过HystrixCommand注解来指定的,如果get()方法内部出现了异常,那么会跳转到hystrixFunction()这个方法中,在这个方法中会返回一些提示信息:
public Object hystrixFunction() {
Map<String,String> result=new HashMap<>();
result.put("info","进入了熔断器定义的方法");
return result;
}
自此,模拟熔断的一个例子完毕,当然实际的情况是非常复杂的,发生的异常也不会仅仅只是这样,很有可能是有一个线程池不断的去访问这个函数,然后不断的消耗线程资源,导致系统资源都被一个服务“吃掉”。
上半部分我们通过了一个简单的测试例子来对Hystrix熔断器进行了一些测试,但是这种方法也有一些弊端,我们在每一个需要的方法上边都加上相应的处理方法才行,这种情况将导致方法数量的膨胀。
是不是有一种方法可以“批量处理”呢?
在消费者端,也即sc07项目中我们通过feign-hystrix来实现。
首先,我们需要打开feign-hystrix,在配置文件中添加下面的代码:
feign.hystrix.enabled=true
然后添加ClientServiceFallbackFactory类来同意处理发生的异常:
@Component
public class ClientServiceFallbackFactory implements FallbackFactory<RemoteService> {
@Override
public RemoteService create(Throwable throwable) {
return new RemoteService() {
@Override
public Object getRemoteService() {
Map<String,String> result=new HashMap<>();
result.put("info","Hystrix error!");
return result;
}
@Override
public Object getRemoteServiceByHystrix() {
Map<String,String> result=new HashMap<>();
result.put("info","Hystrix error!");
return result;
}
};
}
}
最后在RemoteService接口上进行标记:
@FeignClient(value = "SERVICE01",fallbackFactory = ClientServiceFallbackFactory.class)
当我们调用服务提供者的方法出现了错误,我们可以直接在客户端中进行处理。
上述的过程,我们利用Hystrix来同意处理了一些服务提供者中发生的异常,涉及到多个服务,牺牲的是某个服务中的一整个模块,而不是单个服务中的几个函数,上述的处理过程亦称“服务降级”。
最后,Hystrix提供了一个仪表盘来对各种指标进行实时监控,实现方法如下:
添加相关的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
并在启动类上添加相应的注解:@EnableHystrixDashboard
启动之后我们就能够一睹这只猪,偶不,豪猪的芳容:
在下面的域名输入框中输入对应的监控URL(要求服务熔断的方法已经被调用了数次,不然会一直提示连接中...):
注:笔者在这里使用的springboot2.0的版本,在实际的使用中还是遇到了一些小坑:
控制面板需要提供一个类,ServletRegistrationBean,我们可以在启动类中进行添加:
@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;
}
然后在配置文件打开相应的监控权限:
management.endpoint.hystrix.stream.enabled=true
对应的,我们在hystrix的控制面板中输入的url也应该改为:
http://IP:PORT/actuator/hystrix.stream
这个在springboot之前的版本中好像是不会出现的,如果你使用的是springboot2.0版本,可以通过上述的办法来解决这个问题。
好了,关于hystrix的总结就先到此为止吧。