文章目录
前言
专注app软件定制开发本篇主要介绍SpringCloud Fegin专注app软件定制开发结合实现负载均衡的超专注app软件定制开发时参数详解及设置。Feign 专注app软件定制开发自己有两个超时参数,专注app软件定制开发它使用的负载均衡组件 Ribbon 本身还有相关配置。那么,这些配置的优先级是怎样的,又哪些什么坑呢?
一、SpringCloud ?SpringCloud Ribbon?
1、Feign 介绍
Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
3.Ribbon 介绍
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。简单地说,Ribbon是一个客户端负载均衡器。
2.默认配置
所谓默认参数就是没有配置任何相关的超时参数,我们来看看源码里Feign默认的设置是多少:
public class DefaultClientConfigImpl implements IClientConfig { public static final int DEFAULT_READ_TIMEOUT = 5000; public static final int DEFAULT_CONNECTION_MANAGER_TIMEOUT = 2000; public static final int DEFAULT_CONNECT_TIMEOUT = 2000;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
乍一看默认好像connectTimeou为2秒,readTimeout为5s,是不是感觉这个配置没毛病呀,哪怕我就用默认的也都能满足需求,接着我们来看,一个巨大的坑等着你来跳。
/** * Ribbon client default connect timeout. */public static final int DEFAULT_CONNECT_TIMEOUT = 1000;/** * Ribbon client default read timeout. */public static final int DEFAULT_READ_TIMEOUT = 1000;@Bean@ConditionalOnMissingBeanpublic IClientConfig ribbonClientConfig() { DefaultClientConfigImpl config = new DefaultClientConfigImpl(); config.loadProperties(this.name); config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT); config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT); config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD); return config;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
我们来分析一下源码。打开 RibbonClientConfiguration 类后,会看到 DefaultClientConfigImpl 被创建出来之后,ReadTimeout 和 ConnectTimeout 被设置为 1s
4.参数设置
显然1s的超时时间是不行的,如果业务复杂点,或者数据处理比较耗时,或者网络问题,那是很容易触发超时的,那么怎么设置自定义超时时间呢?
ribbon全局配置
ribbon: ReadTimeout: 5000 ConnectTimeout: 5000
- 1
- 2
- 3
ribbon指定服务配置
app-server为服务名
app-server: ribbon: ReadTimeout: 5000 ConnectTimeout: 5000
- 1
- 2
- 3
- 4
Feign全局配置
有两种方法,配置文件和配置类
配置文件
可参考官方文档:
feign: client: config: default: connectTimeout: 5000 readTimeout: 5000
- 1
- 2
- 3
- 4
- 5
- 6
配置类
注册下面的bean即可:
@Beanpublic static Request.Options requestOptions(ConfigurableEnvironment env) { return new Request.Options(10000, 10000);}
- 1
- 2
- 3
- 4
二、坑点1 同时配置 Feign 和 Ribbon 的超时,已谁为准?
还是看源码
在 LoadBalancerFeignClient 源码中可以看到,如果 Request.Options 不是默认值,就会创建一个 FeignOptionsClientConfig 代替原来 Ribbon 的 DefaultClientConfigImpl,导致 Ribbon 的配置被 Feign 覆盖:
public class LoadBalancerFeignClient implements Client { IClientConfig getClientConfig(Request.Options options, String clientName) { IClientConfig requestConfig; //只要Feign的options配置不是默认的,就会使用我们的配置, //反之会使用DefaultClientConfigImpl的实例,这个类实例化请看上面 if (options == DEFAULT_OPTIONS) { requestConfig = this.clientFactory.getClientConfig(clientName); } else { requestConfig = new FeignOptionsClientConfig(options); } return requestConfig; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
三、坑点2 为什么connectTimeout和readTimeout必须同时配置?
如果要配置 Feign 的读取超时,就必须同时配置连接超时,才能生效。这又是为什么呢?
打开 FeignClientFactoryBean 可以看到,只有同时设置 ConnectTimeout 和 ReadTimeout,Request.Options 才会被覆盖:
//此处,必须ConnectTimeout 和ReadTimeout都不为null才会替换新optionsif (config.getConnectTimeout() != null && config.getReadTimeout() != null) { builder.options(new Request.Options(config.getConnectTimeout(), config.getReadTimeout()));}
- 1
- 2
- 3
- 4
- 5
总结
1、Feign如果不设置默认的超时时间,默认的时间是1s。
2、配置 Feign 的读取超时,就必须同时配置连接超时,才能生效,即connectTimeout和readTimeout必须同时配置才能生效。
3、同时配置 Feign 和 Ribbon 的超时,以Feign为准
4、除了可以配置 Feign,也可以配置 Ribbon 组件的参数来修改两个超时时间。这里的坑点三是,参数首字母要大写,和 Feign 的配置不同
感想:Spring Boot 带来了【约定大于配置】,但是,通过这次的学习告诉我们,越是约定大于配置,越是要对那些“默认配置”心里有数才行。