欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hystrix 总结

程序员文章站 2022-07-15 13:02:02
...

 

hystrix是什么?

 

hystrix 是保证系统高可用的框架。主要通过线程资源隔离、熔断、超时、降级、限流来保证。

 

举例说明:

 

比如我们系统中要调用第三方短信发送的服务,如果调用时、出现网络不稳定或短信服务故障时,会造成我们自己系统(tomcat)大量线程阻塞,系统资源耗尽等问题。最终导致系统不可用。

 

在高并发情况下,如果我们直接调用短息服务接口,因有大量的网络 IO 、导致大量的tomcat工作线程被挂起、请求被积压,这时再有其他的请求时,tomcat将会直接拒绝掉。

 

 

综上说述,我们要解决的就是 调用第三方服务出现问题时要有保护机制,不能让三方故障蔓延到整个系统。所以第一个要做的就是线程资源的隔离。

 

资源隔:

线程资源隔离简单来说就是为某个远程服务的相关调用创建一个独立的线程池。当有请求过来时,并非由tomcat工作线程直接请求,而是提交一个task,由线程池里的线程发起调用。如果线程池中没有可用的络程,将进入等待队列,如果等待队列也满了,将直接告知tomcat线程失败(快速失败)。这样就将故障影响范围限制在当前的线程池中。

 

超时:

当tomcat工作线程提交一个task,可设置一个最大等待时间,如果命令(hystrix 都是用令命令提交任务)执时间超过了这个设置,将直接抛出超时异常,避免tomcat工作线程长时间等待导致资源耗尽。

 

 

限流:

如果某个时间出来大量的请求时,处理这个请求需要依赖第三方服务,比如调用微信下单接口。但是微信下单接口调用有频率限制,比如1妙最多5次。这时我们的系统每秒最多处理上线也就5个。这时就需要做一定的限流,直接拒绝一部分请求,避免大量请求积压。hystrix 限流有两种模式:信号量、线程池。两都最大的区别就是信号量只做限流,不会另外开启线程去执行任务。而线程池则是线程耗尽,队列满的情况 下进行限流。

 

降级:

比如,当我们调用数据库获取商品信息时,发现mysql挂了,这时调用肯定会报错,报错就会执行备选方法:getFallback().

我们就可以在getFallback里去获取缓存的商品信息部分数据返给上游,完成降级工作。报错,超时,reject,熔断,都会走降级方法。

 

熔断:

当调用报错()、超时、资源耗尽reject、流量超过一定阈值的前提下,这些情况都会被 短路器记录。当这些异常实践达到一定的设置比例将开发熔断,开启后后面的请求将直接走降级方法。开启经过一段时间后(设置参数)会允许一个请求通过。尝试是否正常了。如果正常则关闭熔断。

 

其他功能:

其他功能如:请求缓存(在一个请求上下文中),请求合并,可视化监控等。

 

 

 

 

代理实例:

 

package com.zzkx.pay.trade.hystrix.command;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.zzkx.pay.trade.retrofit.response.AngelCreateOrderResponse;

import retrofit2.Call;
import retrofit2.Response;

/**
 * @author lyy
 */
public class TestCallCommand extends HystrixCommand<AngelCreateOrderResponse>{
	
	private static final Logger LOG = LoggerFactory.getLogger(TestCallCommand.class);
	
	private Call<AngelCreateOrderResponse> call;

	public TestCallCommand(Call<AngelCreateOrderResponse> call) {
		
		//线程组名称,建议一个服务对应一个组,后续的监控也是以组为单位进行统计
		super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("AngelPayService"))
				//命令的名称,对应服务中的一个方法调用。
				.andCommandKey(HystrixCommandKey.Factory.asKey("AngelCreateOrderCall"))
				//设置线程参数
				.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
						.withCoreSize(10)
						.withMaximumSize(50)
						.withAllowMaximumSizeToDivergeFromCoreSize(true)
						.withKeepAliveTimeMinutes(1)
						.withMaxQueueSize(10)
						.withQueueSizeRejectionThreshold(15))
				//设置熔断器参数
				.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
						//每妙最大通过的请求数,超过这个值将直接开启熔断,走降级方法
						.withCircuitBreakerRequestVolumeThreshold(50)
						//命令执行的超时时间,超过则开启熔断
						.withExecutionTimeoutInMilliseconds(1200)
						//当流程超过RequestVolumeThreshold(50)设置的值并且出错率达到50%的时,开启熔断
						.withCircuitBreakerErrorThresholdPercentage(50)
						//熔断开启后几秒后允许一个流程通过,尝试处理。
						.withCircuitBreakerSleepWindowInMilliseconds(5000)
						//信号量隔离限流策略的设置
						.withFallbackIsolationSemaphoreMaxConcurrentRequests(50))
				
				);
		this.call = call;
		
	}

	@Override
	protected AngelCreateOrderResponse run() throws Exception {
		Response<AngelCreateOrderResponse> response = call.execute();
		return response.body();

	}

	@Override
	protected AngelCreateOrderResponse getFallback() {
		
		Throwable exception = this.getExecutionException();
		if(exception != null) {
			LOG.error(exception.getMessage(),exception);
			//从缓存获取数据返回
		}

		return null;

	}

	
}

 

调用代码:

调用command的执行方法

执行Command有4种方式:execute(),queue(),observe(),toObservable()

其中execute()和queue()仅仅对HystrixCommand适用。

 

TestCallCommand(call).execute()

 

这里传入的call是我使用的retrofit2中的。跟hystrix无关

相关标签: hystrix