亿级流量电商详情页系统实战-42.深入分析hystrix参数

1.缓存

1.1 增加HystrixRequestContextFilter

/**
 * hystrix请求上下文过滤器
 * @author Administrator
 *
 */
public class HystrixRequestContextFilter implements Filter {

	public void init(FilterConfig config) throws ServletException {
		
	}
	
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HystrixRequestContext context = HystrixRequestContext.initializeContext();
		try {
			chain.doFilter(request, response); 
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			context.shutdown();
		}
	}

	public void destroy() {
		
	}

}


@Bean
public FilterRegistrationBean filterRegistrationBean() {
	FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(
			new HystrixRequestContextFilter());
	filterRegistrationBean.addUrlPatterns("/*");
	return filterRegistrationBean;
}

1.2 在command接口中增加getCacheKey

public class GetProductInfoCommand extends HystrixCommand<ProductInfo> {
   ...
	@Override
	protected String getCacheKey() {
		return "product_info_" + productId;
	}
   ...
}

1.2 手工清理缓存

public static class GetterCommand extends HystrixCommand<String> {

    private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("GetterCommand");
    private final int id;

    public GetterCommand(int id) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetSetGet"))
                .andCommandKey(GETTER_KEY));
        this.id = id;
    }

    @Override
    protected String run() {
        return prefixStoredOnRemoteDataStore + id;
    }

    @Override
    protected String getCacheKey() {
        return String.valueOf(id);
    }

    /**
     * Allow the cache to be flushed for this object.
     * 
     * @param id
     *            argument that would normally be passed to the command
     */
    public static void flushCache(int id) {
        HystrixRequestCache.getInstance(GETTER_KEY,
                HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id));
    }

}

public static class SetterCommand extends HystrixCommand<Void> {

    private final int id;
    private final String prefix;

    public SetterCommand(int id, String prefix) {
        super(HystrixCommandGroupKey.Factory.asKey("GetSetGet"));
        this.id = id;
        this.prefix = prefix;
    }

    @Override
    protected Void run() {
        // persist the value against the datastore
        prefixStoredOnRemoteDataStore = prefix;
        // flush the cache
        GetterCommand.flushCache(id);
        // no return value
        return null;
    }
}

2.fallback降级机制

  • hystrix调用各种接口,或者访问外部依赖,mysql,redis,zookeeper,kafka,等等,如果出现了任何异常的情况
  • 对每个外部依赖,无论是服务接口,中间件,资源隔离,对外部依赖只能用一定量的资源去访问,线程池/信号量,如果资源池已满,reject
  • 访问外部依赖的时候,访问时间过长,可能就会导致超时,报一个TimeoutException异常,timeout
  • 对外部依赖的东西访问的时候出现了异常,发送异常事件到短路器中去进行统计,如果短路器发现异常事件的占比达到了一定的比例,直接开启短路,circuit breaker

2.1 配置

public class GetProductInfoCommand extends HystrixCommand<ProductInfo> {
   ...
	@Override
	protected ProductInfo getFallback() {
		ProductInfo productInfo = new ProductInfo();
		productInfo.setName("降级商品");  
		return productInfo;
	}
   ...
}

//HystrixObservableCommand,是实现resumeWithFallback方法

2.2 线程池/队列/信号量满触发fallback

.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
	.withCoreSize(10)
	.withMaxQueueSize(12)
	.withQueueSizeRejectionThreshold(15)) 

.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
   .withFallbackIsolationSemaphoreMaxConcurrentRequests(30)

3.短路器

  • 如果经过短路器的流量超过了一定的阈值,HystrixCommandProperties.circuitBreakerRequestVolumeThreshold(20)
    举个例子,可能看起来是这样子的,要求在10s内,经过短路器的流量必须达到20个;在10s内,经过短路器的流量才10个,那么根本不会去判断要不要短路

  • 如果断路器统计到的异常调用的占比超过了一定的阈值,HystrixCommandProperties.circuitBreakerErrorThresholdPercentage(60)
    如果达到了上面的要求,比如说在10s内,经过短路器的流量(你只要执行一个command,这个请求就一定会经过短路器),达到了30个;同时其中异常的访问数量,占到了一定的比例,比如说60%的请求都是异常(报错,timeout,reject),会开启短路

  • 然后断路器从close状态转换到open状态

  • 断路器打开的时候,所有经过该断路器的请求全部被短路,不调用后端服务,直接走fallback降级

  • 经过了一段时间之后,HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds(5000),会half-open,让一条请求经过短路器,看能不能正常调用。如果调用成功了,那么就自动恢复,转到close状态

  • 短路器,会自动恢复的,half-open,半开状态。断路器半开状态,Open状态过一段时间(默认5s)转为此状态来尝试恢复。此状态时:允许有且仅一个请求进入,一旦请求成功就关闭断路器。请求失败就到Open状态(这样再过5秒才能转到半开状态)

3.1 配置

  • circuitBreaker.enabled

     HystrixCommandProperties.Setter()
       .withCircuitBreakerEnabled(boolean value)
    

    控制短路器是否允许工作,包括跟踪依赖服务调用的健康状况,以及对异常情况过多时是否允许触发短路,默认是true

  • circuitBreaker.requestVolumeThreshold

    HystrixCommandProperties.Setter()
       .withCircuitBreakerRequestVolumeThreshold(int value)
    

    设置一个rolling window,滑动窗口中,最少要有多少个请求时,才触发开启短路。

    举例来说,如果设置为20(默认值),那么在一个10秒的滑动窗口内,如果只有19个请求,即使这19个请求都是异常的,也是不会触发开启短路器的。

  • circuitBreaker.sleepWindowInMilliseconds

    HystrixCommandProperties.Setter()
       .withCircuitBreakerSleepWindowInMilliseconds(int value)
    

    设置在短路之后,需要在多长时间内直接reject请求,然后在这段时间之后,再重新到holf-open状态,尝试允许请求通过以及自动恢复,默认值是5000毫秒

  • circuitBreaker.errorThresholdPercentage

    HystrixCommandProperties.Setter()
       .withCircuitBreakerErrorThresholdPercentage(int value)
    

    设置异常请求量的百分比,当异常请求达到这个百分比时,就触发打开短路器,默认是50,也就是50%

  • circuitBreaker.forceOpen

    HystrixCommandProperties.Setter()
       .withCircuitBreakerForceOpen(boolean value)
    

    如果设置为true的话,直接强迫打开短路器,相当于是手动短路了,手动降级,默认false

  • circuitBreaker.forceClosed

    HystrixCommandProperties.Setter()
       .withCircuitBreakerForceClosed(boolean value)
    

如果设置为ture的话,直接强迫关闭短路器,相当于是手动停止短路了,手动升级,默认false

4.超时

  • execution.isolation.thread.timeoutInMilliseconds

    HystrixCommandProperties.Setter()
       .withExecutionTimeoutInMilliseconds(int value)
    

    (1) 手动设置timeout时长,一个command运行超出这个时间,就被认为是timeout,然后将hystrix command标识为timeout,同时执行fallback降级逻辑。默认是1000,也就是1000毫秒。
    (2) 特别要注意的是,这个时间要设置长一点,因为不仅仅要算接口实际执行的时长,还要计算在队列中到线程池中的时长。

  • execution.timeout.enabled

    HystrixCommandProperties.Setter()
       .withExecutionTimeoutEnabled(boolean value)
    

    控制是否要打开timeout机制,默认是true。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值