首页 > 其他 > 详细

hystrix 超时时间和ribbon的connectTimeout 以及readTimeout 的配置以及原理分析

时间:2020-06-02 16:52:25      阅读:2468      评论:0      收藏:0      [点我收藏+]

背景:

在网上看过很多博客,都是在yml里配置hystrix和ribbon的超时时间,但实践后发现根本没效果,如下面的配置:

技术分享图片

 

 一.先看测试环境搭建:

技术分享图片

 

 order 服务通过feign 的方式调用了product 服务的getProductInfo 接口

//------------ order 服务的调用接口---------------

@FeignClient(name ="product",fallback =ProductHystrix.class)
@Primary
public interface ProductService {
    @RequestMapping("/info/{id}")
    Product getProductInfo(@PathVariable("id") Integer id);
}


@Component
public class ProductHystrix implements ProductService{
    @Override
    public Product getProductInfo(Integer id) {
        System.out.println("被熔断;了");
        Product product = new Product();
        product.setName("熔断了。。。。。");

        return product;
    }
}

// product 服务提供的接口------------------
@Controller
public class ProductController {
    @RequestMapping("/info/{id}")
    @ResponseBody
    @MyLogAnnotation
    public Product getProductInfo(@PathVariable("id") Integer id){
        Product product = new Product();
        product.setId(id);
        product.setName("苹果手机");

        return product;
    }
}

order 服务的application.yml 开启feign:hystrix:enabled: true
二. Hystrix 的超时时间怎么设置:

直接上代码:hystrix 任何相关配置都可以在下面的配置类配置,我这里修改了核心线程数和最大队列数已经超时时间

package com.yang.xiao.hui.order.controller;

import com.netflix.hystrix.*;
import feign.Feign;
import feign.Target;
import feign.hystrix.HystrixFeign;
import feign.hystrix.SetterFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.lang.reflect.Method;


@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
public class FeignConfig {

    @Bean
    @Scope("prototype")
    @ConditionalOnProperty(name = "feign.hystrix.enabled")
    public Feign.Builder feignHystrixBuilder() {
        HystrixFeign.Builder builder = HystrixFeign.builder();
        SetterFactory setterFactory= new SetterFactory(){

            @Override
            public HystrixCommand.Setter create(Target<?> target, Method method) {
                String groupKey = target.name();
                String commandKey = Feign.configKey(target.type(), method);
                //HystrixThreadPoolProperties 线程池相关配置
                HystrixThreadPoolProperties.Setter setter = HystrixThreadPoolProperties.Setter().withCoreSize(100).withMaxQueueSize(200);
                //HystrixCommandProperties 熔断器相关属性配置
                HystrixCommandProperties.Setter setter1 = HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(6000);

                return HystrixCommand.Setter
                        .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                        .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
                        .andThreadPoolPropertiesDefaults(setter)
                        .andCommandPropertiesDefaults(setter1);


            }
        };
        builder.setterFactory(setterFactory);

        return builder;
    }
}

启动服务:通过浏览器输入http://localhost:8674/info/3 调用order 服务

技术分享图片

 

 

 技术分享图片

 

 跟进去看HystrixCommand的创建:

技术分享图片

 

 技术分享图片

 

 由此可见线程池和熔断超时时间都已经改变了,证明我们的配置生效了

原理分析:

在FeignClientsConfiguration这个配置类中有一段代码:

技术分享图片

 

 然后跟进看到默认的对象:

技术分享图片

 

 技术分享图片

 HystrixCommandProperties对象有个默认的超时时间,默认是1s:

技术分享图片

 

 

 那么,我们根据上面的分析,当容器中存在HystrixFeign.builder就不会再创建该bean 了,所以我们可以自己创建一个HystrixFeign.builder 然后调用setterFactory(SetterFactory setterFactory)来修改默认的配置,也就是上面我们自己定义的配置类

熔断器的熔断时间是从调用下面的方法开始计算的:

技术分享图片

 

三.ribbon超时时间怎么设置?

我们继续跟进刚才的调用方法:

技术分享图片

 

 技术分享图片

 

 先看看这个类的值:

技术分享图片

 

 在这里默认连接时间是10s,读取时间是60s,那么这个类是怎么创建的呢?

技术分享图片

 

 技术分享图片

 

 技术分享图片

 

 从上面可以知道,Options对象默认已经有个时间配置了,然而我们继续跟踪代码:

技术分享图片

 

 技术分享图片

 

 技术分享图片

 

 我们看这里:

技术分享图片

 

 技术分享图片

 

 Options对象经过getClientConfig(options, clientName) 方法,就从10s的连接时间变成了1s,60s的读取时间也变成了1s

继续跟进:

技术分享图片

 

 

 技术分享图片

 

 技术分享图片

 

 技术分享图片

 

 至此,我们知道了,默认情况调用第三方服务时,超时时间是1s,那么我们该如何修改呢?

我们回到这里:

技术分享图片

 

 这里说了,如果容器没有该bean才会默认创建,那我们就自己创建一个注入到spring容器中:

在order 服务中:

@Configuration

public class Config {
    @Bean
    public Request.Options feignRequestOptions() {
        Request.Options options = new Request.Options(2000, TimeUnit.MILLISECONDS,
                2000, TimeUnit.MILLISECONDS,
                true);

        return  options;
    }

}

重启,重新调用:

技术分享图片

 

 看到配置已经生效了:

我们这里readTimeout 设置了2秒,如果我们在product服务睡眠3s看看:

product 服务没有睡眠时,正常情况调用结果如下:

技术分享图片

 

product 服务代码修改:

 

技术分享图片

 

 

 order 服务再次调用:
技术分享图片

 

 可见,跟我们想象的一样

如果ribbon的超时时间设置为4s,而hystrix的熔断时间设置为2s看看:

技术分享图片

 

 技术分享图片

 

 再次调用:

技术分享图片

 

 重点是product服务的日志打印:

技术分享图片

 

 证明order 服务熔断了,但product 服务还是被调用了,说明ribbon的时间设置是没问题的

根据上面分析,Hystrix的熔断时间要大于Ribbon的connectTimeout+readTimeout

 技术分享图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

 

hystrix 超时时间和ribbon的connectTimeout 以及readTimeout 的配置以及原理分析

原文:https://www.cnblogs.com/yangxiaohui227/p/13031370.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!