熔断器
雪崩效应
在微服务中通常会有多个服务层的调用,基础服务的故障可能造成级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
熔断器(CircuitBreaker)
熔断器的原理很简单,如同电力过载保护器。它可以实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
熔断器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。 熔断器开关相互转换的逻辑如下图:
熔断器就是保护服务高可用的最后一道防线。
Hystrix特性
1.断路器机制
当Hystrix Commend请求后端服务失败数量达到一定比例(默认50%),断路器会切换到开放状态(open),这是所有的请求会直接失败不会被发送到后端服务。断路器在保持开放一段时间(默认5秒)后会切换到半开放状态(harf-open),这是会 判断下一次请求返回情况,如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN)。一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.
2.fallback
fallback一般是降级操作,对于查询操作,当服务出现问题时,我们可以实现一个fallback方法直接返回结果。fallback的返回值一般是设置的默认值或来自缓存中的值
3.资源隔离
在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.
Feign Hystrix
1.修改配置文件
添加如下配置
feign.hystrix.enabled=true
2.创建回调类
回调类需要实现fengin接口,实现其中方法
@Component
public class SayHiFeginClientHystrix implements SayHiFeginClient {
@Override
public String sayHi2(String name) {
return "SayHiFeginClient error";
}
}
3.fegin接口上添加fallback属性
@FeignClient(value = "service-hi",fallback = SayHiFeginClientHystrix.class) //指定调用的服务名称
public interface SayHiFeginClient {
@RequestMapping("/feign/hi")
String sayHi2(@RequestParam("name") String name);
}
4.测试
实际服务中概率性发生异常,如
@RequestMapping("/feign/hi")
String sayHi2(@RequestParam("name") String name) {
log.info("Feign hi name=" + name);
if(Math.random() > 0.5){
log.error("发生异常");
int a = 1/0;
}
return "Hi " + name;
}
浏览器访问:http://localhost:8764/test?name=pxc
无异常时返回:Hi pxc
异常时返回:SayHiFeginClient error
服务异常时出发fallback,直接返回SayHiFeginClient error