SpringCloud学习(七)--消费者服务基于Hystrix实现容错处理与监控(非Feign客户端服务)

Hystrix,空耳"嗨嘶杰(卷舌)克嘶".由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性、容错性与局部应用的弹性,是一个实现了超时机制和断路器模式的工具类库.

Hystrix主要通过以下几点实现延迟和容错:

包裹请求:使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立的线程中执行,使用了设计模式中的“命令模式”.

回退机制:当请求失败、超时、被拒绝或者当断路器打开时,执行回退方法.回退方法可由开发者设计.

跳闸机制:当某服务的错误率超过一定阈值,Hystrix可以自动或手动跳闸,停止请求该服务一段时间.

资源隔离:Hystrix为每个依赖都维护一个小型线程池,如果该线程池已满,发往该依赖的请求被立即拒绝,而不是排队等候.

自我修复:断路器打开一段时间后,会自动进入"半开"状态.此时断路器可允许一个请求访问依赖的服务,若请求成功,则断路器关闭;否则断路器继续保持“打开”状态.

监控机制:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等. 

 在SpringCloud中使用Hystrix仅需以下步骤实现:

1.引入Hystrix的Maven依赖

2.启动类声明@EnableHystrix注解,为项目启动断路器支持

3.在制定方法上声明@HystrixCommand注解,设置回退方法即可


使用消费者服务整合Hystrix,实现服务降级机制

引入依赖

        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
		</dependency>

启动类声明@EnableHystrix注解

为指定方法声明@HystrixCommand注解,使其具备容错能力.并且指定一个回退方法,使其具备服务降级能力.

这时,仅启动eureka和consumer服务.不启动provider项目,使consumer获取不到provider的实例.

此时,在浏览器输入http://localhost:8181/user/2.查看是否执行回退方法.

由上图测试结果可知,restTemplate对象将找不到springcloud-provider的实例,

满足Hystrix回退机制的请求失败条件,继而执行回退方法(执行回退方法亦可称为服务降级).

服务降级

服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。

注意:虽然当请求失败、超时、被拒绝时,请求都会执行回退方法.但并不意味着断路器已经被打开.

为了验证这点,可以引入Spring Boot Actuator服务监控依赖,通过观察/actuator/health端点就可以得知断路器状态了.


使用Actuator监控Hystrix的状态

引入Actuator依赖

        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

由于Springboot 2.0以上,/actuator/heath端点不显示所有细节.所以需要简单的配置一下/health端点内容范围.

 配置application.yml

management:
  endpoint:
    #允许/actuator/health端点显示所有细节
    health:
      show-details: always      #包含选项never(默认), always, when-authenticated

此时,Actuator完成整合.重启consumer服务.然后在浏览器输入http://localhost:8181/actuator/health

服务端返回的是一串Json字符串,由上图可以看出hystrix的状态是UP,就是一切正常,此时断路器是关闭的.


跳闸机制

在浏览器输入http://localhost:8181/user/2,让consumer服务执行一次回退方法.

回退方法正常执行,浏览器再次输入http://localhost:8181/actuator/health,查看此时的hystrix的状态.

由上图结果可知,尽管Hystrix执行了回退方法,其状态仍然是UP正常的状态.说明断路器并没有开启.

注意:Hystrix跳闸机制说明是当某服务的错误率超过一定阈值(默认是5秒内20次失败),断路器才会开启,此服务自动"跳闸".

为了验证Hystrix的跳闸机制,那么我在5秒内多次请求http://localhost:8181/user/2地址,使其执行多次回退方法即可验证结果.

持续快速的访问http://localhost:8181/user/2地址后,再次输入http://localhost:8181/actuator/health,查看此时的hystrix的状态.

可以看到,此时hystrix状态为CIRCUIT_OPEN,即断路器已经打开了(全开状态:不再请求指定服务).

details节点表示当前服务UserController控制器的getUserById方法断开一段时间对指定服务的请求("跳闸").


自我修复机制

隔一段时间之后,断路器会由全开状态转变为半开状态,允许一个请求访问指定服务,

如果请求成功,则断路器状态将会转变为关闭状态;否则,将继续转变为全开状态.这是Hystrix的自我修复机制.

为了验证Hystrix的自我修复机制,那么我将开启consumer所请求的provider服务.使其能够成功获取provider实例以进行访问.

启动provider服务

此时浏览器输入http://localhost:8181/user/2地址,便可以正常请求,获取用户信息.

再次输入http://localhost:8181/actuator/health,查看此时的hystrix的状态.

可以看出,断路器已变为UP状态,即断路器已经关闭了.


Hystrix的隔离策略

Hystrix存在资源隔离机制, 为每一个依赖(被@HystrixCommand声明的方法)都维护一个小型线程池.当有请求进入该依赖,则为请求开启一个线程进行处理.当线程池满了,发往该依赖的请求被立即拒绝,而不是进入该依赖等待资源.

Hystrix的隔离策略有两种,分别为线程隔离(Hystrix默认使用)和信号量隔离.

THREAD(线程隔离):使用该方式,HystrixCommand将会在单独的线程上执行,并发请求受线程池中的线程数量限制.

SEMAPHORE(信号量隔离):使用该方式,HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受信号量个数限制.  (一般使用于负载非常高、非网络调用和需要传播线程上下文的情况)

Hystrix可使用注解@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")来指定隔离策略.

//指定Hystrix隔离策略为信号量隔离
    @HystrixCommand(fallbackMethod = "getUserByIdFallback", 
                    commandProperties ={
     @HystrixProperty(name="execution.isolation.strategy",value = "SEMAPHORE")})
    @RequestMapping(value = "/user/{id}",method = {RequestMethod.GET})
    public String getUserById(@PathVariable("id")int id){
        //8081为生产者所占用的端口
        //Ribbon会自动的将虚拟主机名映射成服务的网络地址
        return restTemplate.getForObject("http://springcloud-provider/user/"+id,String.class);
    }

Hystrix的监控机制

Hystrix还提供了监控机制,可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等.

可以通过Actuator监控依赖暴露的/actuator/hystrix.stream端点直观感受.

由于Springboot2以上,Actuator只暴露了/health和/info端点,所以首先需要进行简单配置使其暴露所有端点.

配置application.yml

...
management:
  endpoint:
    health:
      show-details: always  # 允许/actuator/health端点显示所有细节
  endpoints:
    web:
      exposure:
        include: "*"  # Springboot2.0以上手动暴露Actuator所有端点

然后重新启动consumer服务即可.此时,访问http://localhost:8181/actuator/hystrix.stream地址

可以看到,浏览器一直处于加载状态并且在页面上不断的输出"ping:"字符.

这是因为consumer服务中,被注解@HystrixCommand依赖的方法还没被请求执行,所以暂时没有监控数据.

此时,通过浏览器访问http://localhost:8181/user/2地址,请求一次consumer服务所依赖的方法.

再次访问http://localhost:8181/actuator/hystrix.stream地址,查看页面内容变化.

此时,系统会不断地刷新获得到监控数据.但是这样形式的数据让人很难有参考价值.

不过好在Netflix提供了配套的断路器仪表盘,可以将这些数据更直观的展示给用户.


Hystrix Dashboard直观展示Hystrix的监控数据

整合Hystrix Dashboard是一件非常简单的事情.按照以下步骤执行即可:

引入依赖

        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
		</dependency>

配置启动类

配置application.yml

hystrix:
  dashboard:
    proxy-stream-allow-list: "*" #防止仪表盘出现【Unable to connect to Command Metric Stream】错误

以上三步执行好后,即可完成对Hystrix Dashboard的整合.此时重启consumer服务.

在浏览器上输入http://localhost:8181/hystrix地址,即可进入仪表盘的主界面.

在最长的那条输入框中输入刚才Hystrix监控数据的地址http://localhost:8181/actuator/hystrix.stream,Title随意输入一个.

然后点击"Monitor Stream"按钮进入数据的直观展示页面.

控制台输出

 Hystrix Dashboard数据展示页面

可以看到,Hystrix Dashboard在等待Hystrix输出信息.此时,访问一次http://localhost:8181/user/2地址,使其执行回退.

此时,仪表盘便会显示具体的参数信息.会不停地刷新获取Hystrix的信息.

仪表盘基本参数参考了https://www.cnblogs.com/zouhong/p/12812898.html.

 由此,Hystrix便整合了Hystrix Dashboard.

若需要将Hystrix Dashboard单独抽离出来,专门作为一个client执行监控服务,则可以为其创建一个springboot项目搭建.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值