Spring WebClient:使用WebFlux.fn + react-addons重试 [英] Spring WebClient: Retry with WebFlux.fn + reactor-addons
本文介绍了Spring WebClient:使用WebFlux.fn + react-addons重试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用Kotlin协程+ WebFlux.fn +反应堆插件为WebClient
添加条件重试:
I'm trying to add a conditional Retry for WebClient
with Kotlin Coroutines + WebFlux.fn + reactor-addons:
suspend fun ClientResponse.asResponse(): ServerResponse =
status(statusCode())
.headers { headerConsumer -> headerConsumer.addAll(headers().asHttpHeaders()) }
.body(bodyToMono(DataBuffer::class.java), DataBuffer::class.java)
.retryWhen {
Retry.onlyIf { ctx: RetryContext<Throwable> -> (ctx.exception() as? WebClientResponseException)?.statusCode in retryableErrorCodes }
.exponentialBackoff(ofSeconds(1), ofSeconds(5))
.retryMax(3)
.doOnRetry { log.error("Retry for {}", it.exception()) }
)
.awaitSingle()
还在重试之前添加条件
if (statusCode().isError) {
body(
BodyInserters.fromPublisher(
Mono.error(StatusCodeError(status = statusCode())),
StatusCodeException::class.java
)
)
} else {
body(bodyToMono(DataBuffer::class.java), DataBuffer::class.java)
}
通话如下:
suspend fun request(): ServerResponse =
webClient/*...*/
.awaitExchange()
.asResponse()
推荐答案
This spring webclient: retry with backoff on specific error gave me the hint to answer the question:
.awaitExchange()
返回ClientResponse
而不是Mono<ClientReponse>
这意味着我的重试是针对bodyToMono
而不是exchange()
的操作.
.awaitExchange()
returns the ClientResponse
and not Mono<ClientReponse>
This means my retry was acting on bodyToMono
instead of the operation of exchange()
.
解决方案现在看起来像
suspend fun Mono<ClientResponse>.asResponse(): ServerResponse =
flatMap {
if (it.statusCode().isError) {
Mono.error(StatusCodeException(status = it.statusCode()))
} else {
it.asResponse()
}
}.retryWhen(
Retry.onlyIf { ctx: RetryContext<Throwable> ->
(ctx.exception() as? StatusCodeException)?.shouldRetry() ?: false
}
.exponentialBackoff(ofSeconds(1), ofSeconds(5))
.retryMax(3)
.doOnRetry { log.error { it.exception() } }
).awaitSingle()
private fun ClientResponse.asResponse(): Mono<ServerResponse> =
status(statusCode())
.headers { headerConsumer -> headerConsumer.addAll(headers().asHttpHeaders()) }
.body(bodyToMono(DataBuffer::class.java), DataBuffer::class.java)
这篇关于Spring WebClient:使用WebFlux.fn + react-addons重试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文