熔断器Hystrix

微服务中服务之间的相互依赖性错综复杂,一个网络请求通常需要调用多个服务实例才能完成。如果一个服务不可用,如网络延迟或故障,会影响依赖于这个服务的其它服务,最后导致整个系统处于瘫痪的状态。为解决这种雪崩效应,引进熔断组件Hystrix,当出现故障后会自动剔除服务实列。Hystrix除了一些基本的熔断器,还能实现服务降级、服务限流的功能,并提供了界面展示健康状态的功能。本章讲诉如何使用RestTemplate和Feign消费服务是使用Hystrix,并介绍Hystrix的工作原理。

Hystrix的设计原则

  • 防止单个服务的故障耗尽整个服务的Servlet容器(如Tomcat)的线程池资源。
  • 快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等待。
  • 提供回退方案,在请求发生故障时,提供设定好的回退方案。
  • 使用熔断器机制,防止故障扩散到其他的服务。
  • 提供熔断器的监控组件Hystrix Dashboard,可以实时监控熔断器的状态。

Hystrix的工作机制

当服务的某个API接口的失败次数在一定时间内小于设定的阈值时,熔断器处于关闭状态,该API接口正常提供服务。当该API接口处理请求的失败次数大于设定的阈值时,Hystrix判定该API接口出现了故障,打开熔断器,这时该API接口会执行快速失败的逻辑,不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器在一定时间后会处于半打开状态,并将一定数量的请求执行正常逻辑,剩余的请求会执行快速失败。若执行正常逻辑的请求失败了,则熔断器继续打开,若成功了,则熔断器关闭。这样熔断器就具有了自我修复的功能。

在RestTemplate上使用熔断器

本章案例在前面章节的案例基础之上进行改造。在讲述ribbon章节时,eureka-ribbon-client工程中我们使用RestTemplate调用了eureka-client的“/hi”接口,并用Ribbon做了负载均衡,现在在此基础上加Hystrix熔断器的功能。

  • 添加Hystrix的起步依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
  • 在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaRibbonClientApplication.class, args);
    }
}
  • 修该RibbonService的代码,在方法中加上@HystrixCommand注解。有了@HystrixCommand方法就用Hystrix熔断器的功能,其中,fallbackMethod为处理回退逻辑的方法,在本例中,直接返回了一个字符串。在熔断器打开的状态下,会执行回退逻辑。回退逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调用其它的服务,这样能执行快速失败,释放线程资源。如果在回退逻辑中一定要调用远程服务,最好在远程调度其它的服务时,也加上熔断器。
public class RibbonServiceHystrix {
    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError")
    public String hiFromClient() {
        return restTemplate.getForObject("http://eureka-client/hi?name=dzy", String.class);
    }
    public String hiError(){
        return "error";
    }
}
  • 启动eureka-server和eureka-ribbon-client。此时没有启动eureka-client,所以eureka-ribbon-client肯定是访问不通eureka-client接口的。此时访问http://localhost:8765/hi,浏览器会显示回退逻辑返回的错误字符串。做到了快速失败,线程不在阻塞。

在Feign上使用熔断器

  • 之前介绍Feign提到本身已经集成了熔断器的功能,Feign的起步依赖已经引入了Hystrix的依赖,所以不需要在pom文件中添加Hystrix的依赖。只需要在配置文件中开启Hystrix功能即可。
feign:
  hystrix:
    enabled: true
  • 在声明式接口中的@FeignClient注解上添加fallback属性来配置快速失败的处理类。该处理类作为Feign熔断器的逻辑处理类,必须实现被@FeignClient修饰的接口,最后需要以Spring Bean的形式注入IoC容器中。
@FeignClient(value = "eureka-client", configuration = FeignClientConfig.class,fallback = HiFailBack.class)
public interface HiFeignClient {
    @GetMapping("/hi")
    String hi(@RequestParam(value = "name") String name);
}
@Component
public class HiFailBack implements HiFeignClient {

    @Override
    public String hi(String name) {
        return "hystrix error";
    }
}
  • 启动eureka-server,eureka-feign-client,此时没有启动eureka-client,所以eureka-feign-client接口调用eureka-client的接口是肯定连接不通的。在浏览器访问eureka-feign-client接口,浏览器会出现配置的错误字符串,说明实现了快速失败。

使用Hystrix Dashboard监控熔断器的状态

Hystrix Dashboard 是监控Hystrix的熔断状况的一个组件,提供了数据监控和友好的图形化展示界面。

在RestTemplate中使用Hystrix Dashboard

在eureka-ribbon-client的基础上改造。

  • 在pom文件中加上Actuator的起步依赖,Hystrix Dashboard的起步依赖。
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
  • 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaRibbonClientApplication.class, args);
    }
}
  • 依此启动eureka-server,eureka-client和eureka-ribbon-client(我的端口为8765),确定两个eureka client已经注册到了eureka server中。
    在浏览器访问http://localhost:8765/hystrix,会出现Hystrix Dashboard的界面。
    image.png

    在界面中依此填写http://localhost:8765/hystrix.stream,200,forezp(任意填写),点击“monitor”,进入界面
    image.png

    监控图中用圆点来表示服务的健康状态,健康度从100%-0%分别会用绿色、黄色、橙色、红色来表示。 另外,这个圆点也会随着流量的增多而变大。 监控图中会用曲线(圆点旁边)来表示服务的流量情况,通过这个曲线可以观察单个接口的流量变化/趋势。对应的指标含义如下
    image.png

在feign中使用Hystrix Dashboard

  • 添加Actuator,Hystrix,Hystrix Dashboard的起步依赖。这里需要注意,既然Feign自带Hystrix,那为什么还需要引入spring-cloud-starter-hystrix?这是因为Feign自带的是Hystrix的依赖不是Hystrix起步依赖。
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
public class EurekaFeignClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaFeignClientApplication.class, args);
    }
}

只需要上述两步就可以在Feign中开启Hystrix Dashboard的功能。

使用Turbine聚合监控

在使用Hystrix Dashboard组件监控服务的熔断状况时,每个服务都有一个Hystrix Dashboard主页,当服务数量很多时,监控非常不方便。为了同时监控多个服务的熔断器的状况,Netflix开源了Hystrix另一个组件Turbine。Turbine用于聚合多个Hystrix Dashboard,将多个Hystrix Dashboard组件的数据放在一个页面上展示,进行集中监控。

  • 新建一个Module工程,取名为turbine-server,在pom中添加turbine,actuator,test的起步依赖。
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
</dependency>

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
 </dependency>
  • 在配置文件application加上相关的配置。
server:
  port: 8770
spring:
  application:
    name: turbine-server
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
management:
  security:
    enabled: false
turbine:
  app-config: eureka-ribbon-client,eureka-feign-client
  cluster-name-expression: new String("default")
  aggregator:
    clusterConfig: default

其中turbine.app-config配置了需要监控的服务名,turbine.cluster-name-expression默认为服务器的集群,此时用默认的即可。turbine.aggregator.clusterConfig可以不写,因为默认就是default。

  • 启动类上添加@EnableTurbine注解,启动Turbine功能
@SpringBootApplication
@EnableEurekaClient
@EnableTurbine
public class TurbineServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TurbineServerApplication.class, args);
    }

}

  • 启动eureka-server,eureka-ribbon-client,eureka-feign-client,turbine-server
    在浏览器访问http://localhost:8765/hystrix,在这个界面为eureka-ribbon-client的
    Hystrix Dashboard界面(用其它服务的Hystrix Dashboard也可,只要监控流为turbine服务器地址就行,但在项目中只会启用一个服务的Hystrix Dashboard),在界面中依此输入监控流的Url地址http://localhost:8770/turbine.stream,监控时间间隔为2000毫秒和title,点击“monitor”,可以看到如下界面。
    image.png

    可以看到这个界面同时聚合了eureka-ribbon-client和eureka-feign-client的Hystrix Dashboard。

总结

在这一章学习了熔断器Hystrix,其中包括什么是Hystrix,Hystrix的工作原理,TestTemplate、Feign结合Hystrix的使用。最后介绍使用图形化监控组件Hystrix Dashboard,以及监控聚合组件Turbine。在下一章中介绍路由网关Zuul。

PS:项目github地址:https://github.com/dzydzydzy/spring-cloud-example.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容