SpringCloud2.x(五)微服务容错处理——Hystrix

系统运行过程中,如果服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直到提供者响应或超时。在高负载情况下,如果不做任何处理,此类问题可能会导致服务消费者的资源耗竭甚至整个系统的崩溃。

一、雪崩效应

把“基础服务故障”导致“级联故障”的现象称为雪崩效应。雪崩效应描述的是提供者不可用导致消费者不可用,并将不可用逐渐放大的过程。

产生原因:在应用中,默认所有的请求都使用一个线程池处理,如下

圈住的是线程池名称,后面的数字是线程编号。 

这样的话,假如一个服务提供者崩溃了或者响应很慢,就会导致消费者调用这个服务的线程一直等待,它的请求多了之后,逐渐地就把线程池中的线程都占用了。然后,消费者调用其它正常的提供者的服务时,也需要等到有空闲的线程才能处理。

二、如何容错

 容错机制需要实现以下两点

  1. 为网络请求设置超时:让资源尽快释放
  2. 使用断路器模式:快速失败

三、使用Hystrix实现容错

1、Hystrix简介

Hystrix是由NetFlix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性。Hystrix主要通过以下几点实现延迟和容错

  • 包裹请求:使用HystrixCommand(或者HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用到了设计模式种的“命令模式”。
  • 跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。
  • 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加快失败判定。
  • 监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。
  • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可由开发人员自行提供,例如返回一个缺省值。
  • 自我修复:当依赖的服务不正常时打开断路器快速失败,从而防止雪崩效应;当发现依赖的服务恢复正常时,又会恢复请求。

2、通用方式整合Hystrix

1)项目的pom.xml文件引入Hystrix的依赖。

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

2)在启动类添加注解@EnableHystrix或@EnableCircuitBreaker,从而为项目启用断路器支持

3)修改服务消费者的OrderController,增加一个API方法以及它的回退方法。

@GetMapping("/order/hystrix_pay")
	@HystrixCommand(fallbackMethod="hystrixPayFallback"
//	commandProperties = {@HystrixProperty(name="属性名", value="属性值")}
	)
	public String hystrixPay() {
		System.out.println("订单服务开始调用支付服务...");
		return restTemplate.getForObject("http://provider-pay/pay", String.class);
	}
	
	public String hystrixPayFallback() {
		return "目标服务请求失败啦!";
	}

API方法加上了@HystrixCommand注解,并设置fallbackMethod属性为回退方法名称。@HystrixCommand还可以通过commandProperties属性设置更多的配置,具体可以设置哪些配置,大家可以网上去找或者通过在com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager类的initializeProperties方法打断点查看。

4)停掉服务提供者项目,启动这个项目,浏览器访问http://localhost:8082/order/hystrix_pay,会展示如下结果

说明当微服务不可用时,进入了回退方法。

3、Hystrix断路器的监控与深入理解

在pom.xml引入如下依赖

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

重新启动项目,访问http://localhost:8082/actuator/health可以看到断路器的状态。

强调一下:执行回退逻辑并不代表断路器已经打开(因为可能还没到达阈值)。请求失败、超时、被拒绝以及断路器打开时等都会执行回退逻辑。

4、Hystrix线程隔离策略与传播上下文

Hystrix的隔离策略有两种

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

SEMAPHOEW(信号量隔离):使用该方式,HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受到信号量个数的限制。

Hystrix默认推荐使用线程隔离,因为这种方式有一个除网络超时以外的额外保护层。如果发生找不到上下文的运行时异常,可考虑将隔离策略设置为信号量隔离。

可使用execution.isolation.strategy属性指定隔离策略。

5、Feign使用Hystrix

将之前编写的feign接口修改成如下内容

/**
 * 支付服务的feign客户端
 * 用fallback属性指定回退类
 * @author z_hh
 * @time 2019年2月17日
 */
@FeignClient(value="provider-pay", fallback=PayFeignClientFallback.class)
public interface PayFeignClient {

	@GetMapping("/pay_with_params")
	public String payWithParams(@RequestParam String orderCode, @RequestParam int totalPrice);
}

/**
 * PayFeignClient对应的回退类,需要实现PayFeignClient接口
 * @author z_hh
 * @time 2019年2月17日
 */
@Component
class PayFeignClientFallback implements PayFeignClient {

	@Override
	public String payWithParams(String orderCode, int totalPrice) {
		return "目标服务请求失败啦!";
	}
	
}

配置文件增加一以下内容。增加超时时间的设置(feign默认1秒钟超时),并打开feign-hystrix(默认是关),一般可以将hystrix的超时时间设置的比feign的超时时间长一些,否则feign的重试(如果配置了)将会失效。

feign:
  client:
    config:
      default:
        connectTimeout: 7000
        readTimeout: 7000
  hystrix:
    enabled: true
 
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 8000

停掉服务提供者项目,启动这个项目,浏览器访问http://localhost:8082/order/feign_pay,同样会展示如下结果

说明当微服务不可用时,进入了回退方法。

6、通过Fallback Factory检查回退原因

很多场景下,需要了解回退的原因。

将Feign接口改为以下内容

/**
 * 支付服务的feign客户端
 * @author z_hh
 * @time 2019年2月17日
 */
@FeignClient(value="provider-pay", fallbackFactory=PayFeignClientFallbackFactory.class)
public interface PayFeignClient3 {

	@GetMapping("/pay_with_params")
	public String payWithParams(@RequestParam String orderCode, @RequestParam int totalPrice);
}

/**
 * 实现FallbackFactory接口,并重写create方法
 * @author z_hh
 * @time 2019年2月17日
 */
@Component
class PayFeignClientFallbackFactory implements FallbackFactory<PayFeignClient3> {

	@Override
	public PayFeignClient3 create(Throwable t) {
		return new PayFeignClient3() {
			
			// 回退方法
			@Override
			public String payWithParams(String orderCode, int totalPrice) {
				return "目标服务请求失败啦!原因:" + t.getMessage();
			}
		};
	}

}

日志最好放在各个fallback方法中,而不要直接放在create方法中。

停掉服务提供者项目,启动这个项目,浏览器访问http://localhost:8082/order/feign_pay,会展示如下结果

 

说明当微服务不可用时,进入了回退方法,并获取到了回退的原因。

7、为Feign禁用Hystrix

配置文件将feign.hystrix.enabled设置为false。

四、使用Hystrix Dashboard可视化监控数据

1)新建一个maven项目microservice-hystrix-dashboard,pom.xml引入以下依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.zhh</groupId>
    <artifactId>microservice-hystrix-dashboard</artifactId>
    <version>1.0</version>
    
    <!-- Spring Boot依赖  -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <!-- Spring Cloud管理依赖  -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
		<!-- hystrix-dashboard -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
    </dependencies>

    <!-- 注意: 这里必须要添加, 否则各种依赖有问题  -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2)配置文件指定服务端口。

server:
  port: 8083

3)启动类增加@EnableHystrixDashboard注解。

@SpringBootApplication
@EnableHystrixDashboard
public class MicroserviceHystrixDashboardApplication {

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

}

4)启动项目,访问http://localhost:8083/actuator/hystrix,看到如下页面说明成功了。

五、使用Turbine聚合监控数据

前面使用/hystrix.stream端点只能监控单个微服务实例,每次查看需要在Hystrix Dashboard上切换想要监控的地址,这显然很不方便。

Turbine是一个聚合Hystrix监控数据的工具,它可将所有相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,从而让集群的监控更加方便。还可以使用消息中间件收集数据。

这里不做详细讲解了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值