断路器Hystrix实现服务容错

一、服务容错

1、服务存在的问题

微服务架构中,生产过程中我们或多或少的会遇到一些问题。如果服务提供者对服务消费者的响应非常的缓慢,那么服务消费对服务提供者的请求就会被迫等待,直到提供者响应或者超时。特别是在高并发的场景中,如果不做任何处理,每个服务消费者都一直请求服务提供者等待响应,大量请求不断涌入,占用消费者资源,最终导致消费者系统崩溃。

如最常见的电商系统,支付系统作为服务提供者,订单系统作为服务消费者。在高并发场景下,大量的订单进来,去请求支付系统进行支付。然而支付系统对来自订单系统的请求影响特别缓慢,订单系统就被迫等待,这时候还不断有来自订单系统的请求。长时间未响应,订单系统付款等待就会超时,导致用户支付失败,用户又重新进行支付,再次增加系统负载量,不仅订单系统面临资源被耗尽的风险,而且支付系统压力更大。

2、引发的雪崩效应

微服务架构中,服务之间存在调用关系是在所难免的,服务多级调用就会形成依赖关系。一旦上层服务不可用,中层服务固然会受影响,依赖中层服务的下层服务难免不熟影响,由上层服务引发的最终导致下层服务不可用,就形成了“级联故障”,这种现象业界一般称之为“雪崩效应”。如下图所示,由服务A引发的不可用最终导致服务C不可用,形成雪崩效应。

3、服务容错的手段

要想防止雪崩效应,大致有以下两种手段:

(1)设置网络超时

正常情况下,服务消费者去请求服务提供者,几十毫秒就可以响应返回。如果服务提供系统不可用或者网络异常,那么响应时间会很长或者最终超时。因此要为服务消费系统设置请求超时时间,这也是传统的做法。

(2)使用断路器模式

这里说的断路器和家用电路的断路器原理一样。家用电路,当电流瞬间过大,电路升温,断路器检测到就会立即切点电路,即自动跳闸,保证电路安全。当电路超载的问题被解决后,关闭断路器,电路就可以恢复正常了。

同理,对某个微服务的请求在短时间内有大量超时,通常说明该服务不可用,在去重新请求已经没有任何意义,只会增加系统资源的消耗。

断路器可以理解为对容易导致错误操作的代理。这种代理能够统计一段时间内调用失败的次数,并决定是正常请去请求服务提供者,还是直接返回失败。

断路器可以实现快速的失败,如果它在一段时间内检测的许多的类似错误(如超时),就会在一段时间之内,强迫对服务的快速调用失败,不在请求依赖的服务,这样消费系统就不再占用系统资源去等待响应超时。

断路器可以自动诊断所依赖的服务是否恢复正常。如果发现所依赖的服务已经恢复正常,那么就会恢复对依赖服务的正常请求。使用这种方式,就可以实现服务的“自我修复”。当依赖的服务不正常时就打开断路器进行快速失败,从而防止雪崩效应;当发现依赖的服务恢复正常时,关闭断路器,恢复正常的请求。

下图展示了断路器转换的逻辑

正常情况下断路器处于关闭状态,可以正常请求依赖的服务。一段时间之后, 请求失败率达到一定阀值,断路器就会打开,此时就会进入快速失败,不再去请求依赖的服务。断路器打开一段时间之后,就会自动进入“半开”状态,半开状态允许一个请求访问依赖服务,如果允许的这个请求能够成功,则关闭断路器;否则继续保持打开状态。

二、Hystrix实现容错

Hystrix是一个实现了超时机制和断路器模式的的工具类库。它由NetFlix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错。

包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令使用独立的线程运行。采用了设计模式中的“命令模式”。

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

资源隔离:Hystrix为每个服务都维护了一个小型线程池(或者信号量)。如果该服务线程池已满, 发往该依赖的请求就会立即被拒绝,而不是排队等候,从而加速失败判定。

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

回退机制:当请求失败、超时、被拒绝,或者断路器打开时,执行回退逻辑,即服务降级,回退逻辑可以由开发人员自行编写。

自我修复:“自我修复”即断路器从打开半开在再到关闭的状态转换,可以参见本文前边的描述。

GitHub地址:https://github.com/Netflix/Hystrix

三、Feign使用Hystrix

1、pom.xml引入maven依赖

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

2、启动类上添加注解@EnableCircuitBreaker,启动断路器。

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringCloudApplication
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.ultrapower.uws"})
public class UwsDataApplication {
    public static void main(String[] args) {
        SpringApplication.run(UwsDataApplication.class);
    }
}

 3、与feign一起使用

import org.springframework.stereotype.Component;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
import java.util.Map;

@FeignClient(name = "uws-data-service", fallback = CollectDeviceHystrixClient.class)
public interface CollectDeviceFeignClient {
    
    @PostMapping(value="/getDeviceLastestPhone")
    String getDeviceLasestPhone(@RequestBody Map<String, Object> map);
}

/**
 * 服务降级处理,回退类实现须CollectDeviceFeignClient接口
 */
@Component
class CollectDeviceHystrixClient implements CollectDeviceFeignClient {

	@Override
	public String getDeviceLasestPhone(Map<String, Object> map) {
		return "no lastest phone";
	}

}

 四、脱离Feign使用

启动类添加@EnableCircuitBreaker,方法上添加@HystrixCommand

@SpringBootApplication
@EnableCircuitBreaker
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

@Component
public class StoreIntegration {

    @HystrixCommand(fallbackMethod = "defaultStores")
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }

    public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
    }
}

注解@HystrixCommand中的fallbackMethod属性指定了失败回退的方法defaultStores。@HystrixCommand注解由名为javanica(https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica)的hystrix-contrib提供。javanica是Hystrix的一个子项目,用于简化Hystrix的使用,SpringCloud自动将带有该注解的SpringBean封装在一个连接到Hystrix断路器的代理中。此外@HystrixCommand的配置非常灵活的,可以使用注解@HystrixProperty中的属性来配置@HystrixCommand。

更多详见https://github.com/Netflix/Hystrix/wiki/Configuration

五、Hystrix的监控

1、基于API的调用的监控

添加maven依赖

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

bootstrap.yml设置包含“hystrix.stream”

management:
  endpoints:
    web:
      exposure:
        include: ["hystrix-stream"]

 访问如: http://locahost:8080/actuator/hystrix.stream

2、基于Dashboard可视化监控

1、独立使用

引入maven依赖

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

启动类添加注解@EnableHystrixDashboard

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;

@SpringCloudApplication
@EnableHystrixDashboard
public class UwsDataApplication {
    public static void main(String[] args) {
        SpringApplication.run(UwsDataApplication.class);
    }
}

application.yml配置端口

Server: 
    port: 8030

访问http://locahost:8030/hystrix.stream,也可以与Eureka结合

2、把hystrix-dashboard注册到Eureka Server

启动类添加@EnableHystrixDashboard和@EnableDiscoveryClient

配置application.yml

server:
  port: 8030

spring:
  application:
    name: uws-hystrix-dashboard

#eureka
eureka:
  client:
    service-url:
      defaultZone: http://uws:uws@localhost:8761/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}

访问http://locahost:8030/hystrix.stream

参考:《Spring Cloud与Docker微服务架构实战》周立

参考:https://github.com/Netflix/Hystrix/

 参考:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值