spring-boot - Spring WebClient 多次重试时处理不同的错误
问题描述
我可以添加多个retryWhen
来执行重试以处理不同的 WebClient 故障响应吗?
我想要达到的目标:
我正在使用 WebClient 进行 REST API 调用。很少有错误场景,发生时我需要执行重试,但延迟不同。
例如,1.如果401 Unauthorize
发生,我可以在刷新令牌后立即重试。2. 如果502/503 Server
发生错误,我需要延迟 5 秒后重试。3.如果429 Too Many Request
发生,我需要延迟重试时间,比如20秒后。
我想创建如下重试规范:
protected static final Predicate<Throwable> is401 =
(throwable) -> throwable instanceof WebClientResponseException.Unauthorized;
protected static final Predicate<Throwable> is5xx =
(throwable) -> throwable instanceof WebClientResponseException.ServiceUnavailable;
protected static final Predicate<Throwable> is429 =
(throwable) -> throwable instanceof WebClientResponseException.TooManyRequests;
Retry retry401 = Retry.fixedDelay(5, Duration.ofSeconds(1))
.filter(is401)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> retrySignal.failure());
Retry retry5xx = Retry.fixedDelay(5, Duration.ofSeconds(10))
.filter(is5xx)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> retrySignal.failure());
Retry retry429 = Retry.fixedDelay(5, Duration.ofSeconds(20))
.filter(is429)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> retrySignal.failure());
// trying to apply the to WebClient like below:
WebClient.Builder()
.get()
.uri("endpointuri")
.retrieve()
.bodyToFlux(String.class)
.retryWhen(retry401)
.retryWhen(retry5xx)
.retryWhen(retry429);
看起来 `.retryWhen(retry429)' 会覆盖其他重试。
解决方案
看起来 `.retryWhen(retry429)' 会覆盖其他重试。
这是错误的。retryWhen
是一个基于现有发布者的复合运算符 - 您可以将其链接多次。您唯一需要担心一次重试“覆盖”另一次的情况是您的filter
谓词重叠时。
即使在这种情况下,看起来它是“第一次获胜”(在链中)而不是“最后一次获胜”。
相反,您的问题可能与此行有关:
protected static final Predicate<Throwable> is5xx =
(throwable) -> throwable instanceof WebClientResponseException.ServiceUnavailable;
从您的命名和描述来看,您似乎希望它捕获任何 5xx 错误 - 但它只会捕获 503(专门分配给“服务不可用”。)
如果您尝试使用不同的东西,例如 502 或 500 错误 - 那么您定义的所有谓词(因此重试)都不会匹配。
相反,要检查任何 5xx 错误,您可能需要:
protected static final Predicate<Throwable> is5xx =
(throwable) -> throwable instanceof WebClientResponseException && ((WebClientResponseException)throwable).getStatusCode().is5xxServerError();
推荐阅读
- python - Pythin kivy如何关闭纹理抗锯齿
- html - 当用户将鼠标悬停在一个元素上时,会更改另一个元素的属性
- conditional-statements - 条件翻译方案
- r - 如何测试我的迭代是否无限运行?
- swift - 得到“编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式”
- awk - awk - 两个文件之间的几列的部分匹配,并返回两个文件的一行,用逗号连接
- javascript - 如何在网页中与套接字共享屏幕?
- php - HTML/CSS 下拉菜单进入 WordPress 动态菜单
- javascript - 有没有办法在更新列表中的 DOM 时显示 JSON 数据?
- number-formatting - 这些数字是否有可能是相同的值?徽章阅读器,rfid