走进Spring Cloud之六 Hystrix(监控和断路器)(Greenwich版本)

走进Spring Cloud之六 Hystrix(监控和断路器)(Greenwich版本)

Hystrix(监控和断路器)

断路器模式源于Martin Fowler的Circuit Breaker一文。“断路器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),直接切断原来的主逻辑调用。但是,在Hystrix中的断路器除了切断主逻辑的功能之外,还有更复杂的逻辑。

正常情况下,当整个服务环境中,某一个服务提供方由于网络原因、数据库原因或者性能原因等,造成响应很慢的话,调用方就有可能短时间内累计大量的请求线程,最终造成调用方down,甚至整个系统崩溃。而加入hystrix之后,如果hystrix发现某个服务的某台机器调用非常缓慢或者多次调用失败,就会短时间内把这条路断掉,所有的请求都不会再发到这台机器上。

如果某个服务所有的机器都挂了,hystrix会迅速失败,马上返回,保证被调用方不会有大量的线程堆积。

使用eureka时,当一个服务提供方挂掉以后,服务订阅者最长可能30s以后才知道,那这30s就会出现大量的调用失败。如果在系统里面集成了hystrix,就会马上把挂掉的这台服务提供方断路掉,让请求不再转发到这台机器上,大量减少调用失败。
hystrix执行断路操作以后,并不表示这条路就永远断了,而是会一定时间间隔内缓慢尝试去请求这条路,如果能请求成功,断路就会恢复。

有一点需要注意的是hystrix在做断路时,默认所有的调用请求都会放在一个的线程池中进行,线程池的作用很明显,有隔离性。比如gateway,集成了5个子业务系统,可能其中一个系统的调用量非常大,而另外四个系统的调用很小,如果没有线程池的话,显然第一个系统的大量调用会影响到后面四个系统的调用性能。hystrix的线程池和java标准线程池一样,可以配置一些参数:coreSize、maximumSize、maxQueueSize、queueSizeRejectionThreshold、allowMaximumSizeToDivergeFromCoreSize、keepAliveTimeMinutes等,如果某一个子系统的调用量突然激增,超过了线程池的容量,也会迅速失败,直接返回,起到降级和保护系统本身的作用。当然hystrix也支持非线程池的方式,在本地请求线程中做调用,即semaphore模式,官方不建议,除非系统qps真的很大。

Hystrix案例

Feign默认集成了Hystrix。我们可以在上一个moudle service-consumer中增加熔断特性。

application.yml

在application.ym添加feign.hystrix.enabled=true开启Hystrix。

server:
  port: 8080

spring:
  application:
    name: service-consumer

eureka:
  client:
    service-url:
      #设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka ;多个地址可使用 , 分隔。
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/

#开启Hystrix
feign:
  hystrix:
    enabled: true

FeignServiceHystrix.java

新建FeignServiceHystrix.java实现feign接口用于熔断处理:

@Component
public class FeignServiceHystrix implements FeignExampleService {

    @Override
    public String hello(@RequestParam(value = "name") String name) {
        return "sorry "+name+",service has fail!";
    }
}

FeignExampleService.java

修改FeignClient增加fallback熔断处理

@FeignClient(value = "service-producer",fallback = FeignServiceHystrix.class)
public interface FeignExampleService {

    @GetMapping("hello")
    public String hello(@RequestParam(value = "name") String name);

}

启动测试

此时启动service-consumer但是关闭服务提供者service-producer。

再次访问 localhost:8761

hystrix

再次访问页面http://localhost:8080/hello/jason
调用的结果如下:
failed

GitHub源代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值