Hystrix生产环境配置实践

2019/06/13 15:26
阅读数 2.9K

线程池资源优化演进

在生产环境中部署一个短路器,一开始需要将一些关键配置设置的大一些,比如timeout超时时长,线程池大小,或信号量容量,然后逐渐优化这些配置,直到在一个生产系统中运作良好。

(1)一开始先不要设置timeout超时时长,默认就是1000ms,也就是1s
(2)一开始也不要设置线程池大小,默认就是10
(3)直接部署hystrix到生产环境,如果运行的很良好,那么就让它这样运行好了
(4)让hystrix应用,24小时运行在生产环境中
(5)依赖标准的监控和报警机制来捕获到系统的异常运行情况
(6)在24小时之后,看一下调用延迟的占比,以及流量,来计算出让短路器生效的最小的配置数字
(7)直接对hystrix配置进行热修改,然后继续在hystrix dashboard上监控
(8)看看修改配置后的系统表现有没有改善

 

HystrixThreadPool线程数量设定计算公式

每秒的高峰访问次数 * 99%的访问延时 + 缓冲数量

假设一个依赖的服务的高峰访问次数30QPS,99%的请求延时实践在200ms,那么我们可以设定的线程数量=30*0.2+4=10个线程。

HystrixCommand线程超时timeout设定

结合线程池数量配置,设置能够完成执行高峰时QPS任务的timeout数值。

默认线程超时为1s。假设一个依赖服务的高峰访问时,99.5%的请求延时在250ms,假设再允许服务重试一次消耗50ms,那么这个依赖服务的延时设置为300ms就可以了,这样一个线程最多延时300ms,也就是这个线程每秒能执行三次依赖服务,线程池中10个线程,整好能处理30QPS。如果把延时设置为400ms,那么一个线程每秒最多执行2次请求,10个线程在1s内最多执行20个请求,剩余的10个请求就会被线程池阻塞住,再来新的请求也继续会被阻塞住,如果等待队列已满,那么新来的请求就会被直接Reject。所以400ms的超时设置就不能满足30QPS的请求次数要求。

生产环境中动态分配线程池资源

线程池动态配置选项

//允许线程池自动从coreSize扩容到maximumSize

.withAllowMaximumSizeToDivergeFromCoreSize(true)

//default 10,默认线程池大小

.withCoreSize(10)

//最大线程数

.withMaximumSize(30)

//空闲线程存活时间1分钟,超时后线程池数量自动恢复到coreSize大小

.withKeepAliveTimeMinutes(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
@Slf4j
public class GetProductInfoWithDynamicThreadPoolCmmd extends HystrixCommand<ProductInfo> {

    private static final HystrixCommandKey KEY = HystrixCommandKey.Factory.asKey("GetProductInfoCmmd");

    private Long productId;

    public GetProductInfoWithDynamicThreadPoolCmmd(Long productId) {
        super(
                Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetProductInfoGroup"))
                        .andCommandKey(HystrixCommandKey.Factory.asKey("GetProductInfoCmmd"))
                        .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("GetProductInfoThreadPool"))
                        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                                //允许执行的最大并发数
                                .withExecutionIsolationSemaphoreMaxConcurrentRequests(30)
                                //请求超时
                                .withExecutionTimeoutInMilliseconds(300))
                        .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                                //允许线程池自动从coreSize扩容到maximumSize
                                .withAllowMaximumSizeToDivergeFromCoreSize(true)
                                //default 10,默认线程池大小
                                .withCoreSize(10)
                                //最大线程数
                                .withMaximumSize(30)
                                //空闲线程存活时间1分钟,超时后线程池数量自动恢复到coreSize大小
                                .withKeepAliveTimeMinutes(1)
                                //default 5,没有被线程池执行的请求会放到队
							 //列中等待线程,如果队列已满,新来的请求会被降级被拒
                                .withQueueSizeRejectionThreshold(10)
                                //withQueueSizeRejectionThreshold和withMaxQueueSize比较,queueSize取较小值
                                .withMaxQueueSize(8))
        );
        this.productId = productId;
    }

    @Override
    protected ProductInfo run() throws Exception {
        String url = "http://127.0.0.1:8082/product/get?productId="+productId;

        String s = HttpClientUtils.sendGetRequestWithException(url);
        log.info("product-ha response {}",s);
        ProductInfo productInfo = JSONObject.parseObject(s, ProductInfo.class);
        return productInfo;
    }

    /**
     * 从hystrix本地缓存中获取数据,而不是执行run方法
     * @return
     */
    @Override
    protected String getCacheKey() {
        return "product_key_"+productId;
    }

    /**
     * 清理hystrix缓存的数据
     * @param productId
     */
    public static void flushCache(Long productId){
        HystrixRequestCache.getInstance(KEY,HystrixConcurrencyStrategyDefault.getInstance()).clear("product_key_"+productId);
    }

    /**
     * hystrix执行降级请求时返回的数据
     * @return
     */
    @Override
    protected ProductInfo getFallback() {
        return null;
    }
}
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部