前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud详细教程 | 第四篇:断路器客户端Hystrix(Greenwich版本)

SpringCloud详细教程 | 第四篇:断路器客户端Hystrix(Greenwich版本)

作者头像
小东啊
发布2019-06-26 15:24:39
1K0
发布2019-06-26 15:24:39
举报
文章被收录于专栏:李浩东的博客李浩东的博客

一. 简介

Hystrix已经停止开发,官方替代项目Resilience4j,虽然官方已经不推荐使用,想来想去还是得说下,简单介绍下

1.名字的由来?

hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名为Hystrix,并使用了对应的卡通形象做作为logo。

2.什么是Hystrix?

在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。

3.熔断器图

Netflix的创造了一个调用的库Hystrix实现了断路器图案。在微服务架构中,通常有多层服务调用。

HystrixGraph

图1.微服务图 较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。

HystrixFallback 图2. Hystrix回退防止级联故障 开放式电路会停止级联故障,并允许不必要的或失败的服务时间来愈合。回退可以是另一个Hystrix保护的调用,静态数据或一个正常的空值。回退可能被链接,所以第一个回退使得一些其他业务电话又回到静态数据。

4.为什么要用?

来自 https://www.jianshu.com/p/138f92aa83dc

在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,Dubbo等),在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢,资源繁忙,暂时不可用,服务脱机等。

当依赖阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性,在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。

例如:一个依赖30个SOA服务的系统,每个服务99.99%可用。 99.99%的30次方 ≈ 99.7% 0.3% 意味着一亿次请求 会有 3,000,00次失败 换算成时间大约每月有2个小时服务不稳定. 随着服务依赖数量的变多,服务不稳定的概率会成指数性提高.

5.Hystrix设计理念

想要知道如何使用,必须先明白其核心设计理念,Hystrix基于命令模式,通过UML图先直观的认识一下这一设计模式

可见,Command是在Receiver和Invoker之间添加的中间层,Command实现了对Receiver的封装。那么Hystrix的应用场景如何与上图对应呢?

API既可以是Invoker又可以是reciever,通过继承Hystrix核心类HystrixCommand来封装这些API(例如,远程接口调用,数据库查询之类可能会产生延时的操作)。就可以为API提供弹性保护了。

6.Hystrix如何解决依赖隔离

1:Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。 2:可配置依赖调用超时时间,超时时间一般设为比99.5%平均时间略高即可.当调用超时时,直接返回或执行fallback逻辑。 3:为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。 4:依赖调用结果分:成功,失败(抛出异常),超时,线程拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行fallback(降级)逻辑。 5:提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10秒),熔断器默认错误率阈值为50%,超过将自动运行。 6:提供近实时依赖的统计和监控

7.Hystrix流程结构解析

流程说明: 1:每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中. 2:执行execute()/queue做同步或异步调用. 3:判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤. 4:判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤. 5:调用HystrixCommand的run方法.运行依赖逻辑 5a:依赖逻辑调用超时,进入步骤8. 6:判断逻辑是否调用成功 6a:返回成功调用结果 6b:调用出错,进入步骤8. 7:计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态. 8:getFallback()降级逻辑. 以下四种情况将触发getFallback调用: (1):run()方法抛出非HystrixBadRequestException异常。 (2):run()方法调用超时 (3):熔断器开启拦截调用 (4):线程池/队列/信号量是否跑满 8a:没有实现getFallback的Command将直接抛出异常 8b:fallback降级逻辑调用成功直接返回 8c:降级逻辑调用失败抛出异常 9:返回执行成功结果

二. 使用Hystrix

本文介绍Ribbon+RestTemplate与Hystrix的使用以及Hystrix与Feign的使用

1.Ribbon+RestTemplate与Hystrix的使用

在之前的ribbon-server服务工程进行改造 增加Hystrix依赖

代码语言:javascript
复制
        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>        </dependency>

在程序启动入口类加上@EnableHystrix 用来开启Hystrix功能

代码语言:javascript
复制
package com.li.ribbonserver;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.context.annotation.Bean;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;
@EnableHystrix // 开启Hystrix功能@RestController@EnableEurekaClient@SpringBootApplicationpublic class RibbonServerApplication {
    public static void main(String[] args) {        SpringApplication.run(RibbonServerApplication.class, args);    }

    @Bean    @LoadBalanced // 开启负载均衡    RestTemplate restTemplate() {        return new RestTemplate();    }


    @RequestMapping("/hello")    public String hello(String name) {
        // 地址直接写服务名称即可        String hello = this.restTemplate().getForObject("http://eureka-client/hello?name" + name, String.class);        return hello;    }

}

改造RibbonServerApplication类,在hello方法上加上@HystrixCommand注解

该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断回调方法,回调方法会返回异常信息等

代码语言:javascript
复制
package com.li.ribbonserver;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.context.annotation.Bean;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;
@EnableHystrix // 开启Hystrix功能@RestController@EnableEurekaClient@SpringBootApplicationpublic class RibbonServerApplication {
    public static void main(String[] args) {        SpringApplication.run(RibbonServerApplication.class, args);    }

    @Bean    @LoadBalanced // 开启负载均衡    RestTemplate restTemplate() {        return new RestTemplate();    }

    // 发生熔断时 会调用我们自定义的异常方法 则执行fallback    @HystrixCommand(fallbackMethod = "helloError")    @RequestMapping("/hello")    public String hello(String name) {
        // 地址直接写服务名称即可        String hello = this.restTemplate().getForObject("http://eureka-client/hello?name" + name, String.class);        return hello;    }
    public String helloError(String name) {        return "服务器异常,请稍后再试";    }
}

现在依次启动eureka-server eureka-client一个实例就可以了ribbon-server 项目启动完成后, 打开浏览器访问: http://localhost:8761/

服务都已经注册进来了 浏览器访问: http://localhost:8765/hello?name=lhd

说明服务一切正常 现在模拟服务挂掉 将eureka-client服务关闭 再次访问 http://localhost:8765/hello?name=lhd

说明熔断器已经生效

  1. Feign的使用

来自官方文档

Feign 自带Hystrix支持, 如果Hystrix在类路径上,feign.hystrix.enabled=true,Feign将用断路器包装所有方法

在feign-server服务配置文件加上feign.hystrix.enabled=true用来开启熔断器

代码语言:javascript
复制
# 端口号server.port=8766# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=feign-server#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/# 支持hystrixfeign.hystrix.enabled=true

feign使用非常简单,只需要在注解@FeignClient上加上fallback并指向异常回调类就可以了

代码语言:javascript
复制
package com.li.feignserver.server;

import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;
/** * eureka-client 是调用的服务名 */@FeignClient(value = "eureka-client",fallback = EurekaCclientServiceHystric.class)public interface EurekaCclientService {
    @GetMapping(value = "/hello")    String hello(@RequestParam(value = "name") String name);}package com.li.feignserver.server;
import org.springframework.stereotype.Component;
/** * @Classname EurekaCclientServiceHystric * @Description 回调异常 * @Author 李号东 lihaodongmail@163.com * @Date 2019-03-28 22:58 * @Version 1.0 */@Componentpublic class EurekaCclientServiceHystric implements EurekaCclientService{
    @Override    public String hello(String name) {        return "调用eureka-client服务异常:调用"+name;    }}

然后启动feign-server工程 打开浏览器访问: http://localhost:8766/hello?name=lhd

说明熔断器已经生效

源码下载: https://github.com/LiHaodong888/SpringCloudLearn

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 李浩东的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 简介
    • 1.名字的由来?
      • 2.什么是Hystrix?
        • 3.熔断器图
          • 4.为什么要用?
            • 5.Hystrix设计理念
              • 6.Hystrix如何解决依赖隔离
                • 7.Hystrix流程结构解析
                • 二. 使用Hystrix
                  • 1.Ribbon+RestTemplate与Hystrix的使用
                  相关产品与服务
                  微服务引擎 TSE
                  微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档