Feign重试与超时机制:请求失败后的等待时序疑问
Feign重试与超时的执行顺序解析
当前配置代码
Feign重试器配置
@Bean public Retryer retryer() { /* * It'll retry only a given number of times, will start with some time interval, and then increase it with each retry up to provided maximum. * Let's define it with starting interval of 100 milliseconds, the maximum interval of 3 seconds, and the maximum number of attempts of 5: */ return new Retryer.Default(100L, TimeUnit.SECONDS.toMillis(3L), 5); }
自定义超时与代理配置
@Bean public Builder proxyFeignBuilder() { OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); if (StringUtils.isNotEmpty(proxyHost)) { final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); okHttpClient = new OkHttpClient.Builder().proxy(proxy).build(); } return Feign.builder().options(new Request.Options(feignConnectTimeout, TimeUnit.MILLISECONDS, feignReadTimeout, TimeUnit.MILLISECONDS, true)) .client(new feign.okhttp.OkHttpClient(okHttpClient)); }
你的疑问
你对请求失败后的等待时间顺序的理解是否正确:
- 根据错误类型,最多等待feignConnectTimeout与feignReadTimeout中的较大值。
- 然后等待100ms。
- 首次重试,再次执行步骤1的等待逻辑。
- 然后等待100ms至3秒之间的时长。
- 第二次重试,再次执行步骤1的等待逻辑。
- 以此类推。
- 第五次尝试前等待3秒。
- 最后一次重试,再次执行步骤1的等待逻辑。
正确的执行顺序
你的理解存在偏差,实际执行顺序如下:
- 发起请求阶段:请求过程受
feignConnectTimeout(连接超时)和feignReadTimeout(读取超时)分别限制:- 连接阶段最多等待
feignConnectTimeout时长,超时则触发重试判定; - 连接成功后,读取响应阶段最多等待
feignReadTimeout时长,超时也触发重试判定。
- 连接阶段最多等待
- 重试等待阶段:请求失败且符合重试条件时,进入等待逻辑:
- 第一次重试前:等待100ms(初始间隔);
- 第二次重试前:等待时长为前一次间隔的1.5倍(默认指数退避规则),但不超过3秒的最大值;
- 后续每次重试前的等待时长按指数递增,直到达到3秒后保持该间隔不变。
- 重试执行阶段:等待结束后发起重试请求,重复上述超时限制逻辑;
- 循环终止条件:直到完成5次尝试(包含首次请求),即最多重试4次(因为
maxAttempts=5,首次是第1次,之后重试4次)。
举个具体流程示例:
- 第1次请求:受连接/读取超时限制,失败后等待100ms;
- 第2次请求:受超时限制,失败后等待150ms(100*1.5);
- 第3次请求:受超时限制,失败后等待225ms(150*1.5);
- 第4次请求:受超时限制,失败后等待337.5ms,依此类推,直到间隔达到3000ms后不再增长;
- 第5次请求:这是最后一次尝试,完成后不再重试。
注意:重试仅针对Feign默认判定为可重试的错误类型(如IO异常、5xx状态码等),并非所有请求失败都会触发重试。
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

