http客户端超时重试机制笔记
超时设置:
Feign_Ribbon 超时机制
结论一,默认情况下 Feign 的读取超时是 1 秒,如此短的读取超时算是坑点一。
结论二,也是坑点二,如果要配置 Feign 的读取超时,就必须同时配置连接超时,才能生效。
结论三,单独的超时可以覆盖全局超时,这符合预期,不算坑
除了可以配置 Feign ,也可以配置 Ribbon 组件的参数来修改两个超时时间。这里的坑点三是,参数首字母要大写,和 Feign 的配置不同。
结论五,同时配置 Feign 和 Ribbon 的超时,以 Feign 为准。
Feign 可以设置对某个 FeignClient 设置超时,也支持对某个接口设置超时:
https://github.com/JosephZhu1983/java-common-mistakes/blob/master/src/main/java/org/geekbang/time/commonmistakes/httpinvoke/feignpermethodtimeout/FeignPerMethodTimeoutController.java
Feign 比较新的版本才会支持对某个接口设置超时:
https://github.com/OpenFeign/feign/pull/970
来自 <https://time.geekbang.org/column/article/213273>
相关设置示例:
clientsdk.ribbon.listOfServers=localhost:45678
feign.client.config.default.readTimeout=3000
feign.client.config.default.connectTimeout=3000
ribbon.ReadTimeout=4000
ribbon.ConnectTimeout=4000
httpClient 超时机制
//从连接池中获取连接的超时时间
.setConnectionRequestTimeout(config.connReqTimeout)
//与服务器连接超时时间:会创建一个异步线程用以创建socket连接,此处设置该socket的连接超时时间
.setConnectTimeout(config.connTimeout)
//socket读数据超时时间:从服务器获取响应数据的超时时间
.setSocketTimeout(config.socketTimeout)
nginx 超时设置:
location /wukong {
proxy_pass http://127.0.0.1:8883/;
proxy_set_header Host $http_host;
proxy_request_buffering off; //不缓存请求数据
proxy_read_timeout 3600000s; //读取超时
proxy_send_timeout 3600000s; //写入超时
}
对类似数据库连接池的重要资源进行持续检测,并设置一半的使用量作为报警阈值,出现预警后及时扩容。
假设我们希望设置连接超时5s,获取连接超时10s:
hikari两个参数设置方式:
spring.datasource.hikari.connection-timeout=10000
spring.datasource.url=jdbc:mysql://localhost:6657/common_mistakes
?connectTimeout=5000
&characterEncoding=UTF-8
&useSSL=false&rewriteBatchedStatements=true
jedis两个参数设置:
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxWaitMillis(10000);
try (JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379, 5000);
Jedis jedis = jedisPool.getResource()) {
return jedis.set("test", "test");
}
重试机制:
Feign+Ribbon重试机制:
Get 请求在某个服务端节点出现问题(比如读取超时)时,Ribbon 会自动重试一次,禁用方法:
一是,把发短信接口从 Get 改为 Post 。其实,这里还有一个 API 设计问题,有状态的 API 接口不应该定义为 Get 。根据 HTTP 协议的规范, Get 请求用于数据查询,而 Post 才是把数据提交到服务端用于修改或新增。选择 Get 还是 Post 的依据,应该是 API 的行为,而不是参数大小。
二是,将 MaxAutoRetriesNextServer 参数配置为 0 ,禁用服务调用失败后在下一个服务端节点的自动重试。在配置文件中添加一行即可: ribbon.MaxAutoRetriesNextServer=0
Nginx重试机制
proxy_next_upstream :语法: proxy_next_upstream
[error|timeout|invalid_header|http_500|http_503|http_404|off]
默认值: proxy_next_upstream error timeout
即 error timeout会自动重试
可以修改默认值,在去掉error和timeout,这样在发生错误和超时时,不会重试
proxy_next_upstream_tries 这个参数决定重试的次数,0表示关闭该参数
Limits the number of possible tries for passing a request to the next server. The 0 value turns off this limitation.
HttpClient 重试机制
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
builder.setDefaultRequestConfig(requestConfig);
builder.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
return builder;