http客户端超时重试机制笔记

JavaLegend宝哥

共 4459字,需浏览 9分钟

 ·

2023-08-24 22:36

超时设置:

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"63795000);

            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(0false));

    return builder;


浏览 69
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报