You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJava Single重试未触发服务端请求问题排查求助

问题排查与修复方案

核心问题

你这段代码的关键bug在于:gRPC Stub的超时时间(deadline)是绑定在实例上的一次性配置。你提前创建了带deadline的Stub,第一次请求失败触发重试时,复用的是同一个已经过期的Stub实例,导致重试请求直接在客户端超时失败,根本没发往服务端,所以服务端收不到新请求。

具体原因拆解

看你写的代码:

return Single.fromFuture(
        asyncStub.withDeadlineAfter(ClientConfiguration.INSTANCE.getMaxTimeout(), TimeUnit.SECONDS).checkBalance(payload))
        .doOnSubscribe(s -> System.out.println("subscribing"))
        .doOnSuccess((resp) -> {
                    log.info("Check Balance got response success {}", resp.getUserID());
                    log.debug("Check Balance got response success {}", resp.toString());
                })
        .doOnError(throwable -> {
                    this.logError(throwable, "Check balance userid:" + payload);
                })
        .retry((retryCount, error) -> retryCount < 3).toFuture();
  • asyncStub.withDeadlineAfter(...)会生成一个新的Stub,但这个Stub的deadline是从调用那一刻开始算的固定时长,过期就失效。
  • 当第一次请求失败触发重试时,Single.fromFuture()里的代码不会重新执行——也就是说不会重新创建带新deadline的Stub,而是拿已经过期的旧Stub去发请求,结果就是请求直接在客户端挂掉,没到服务端。

修复代码

要让每次重试都用全新的、有有效deadline的Stub,得把Stub的创建逻辑放到Single.defer()里,确保每次重试都会重新生成带新超时的Stub:

return Single.defer(() -> 
        Single.fromFuture(
            asyncStub.withDeadlineAfter(ClientConfiguration.INSTANCE.getMaxTimeout(), TimeUnit.SECONDS)
                .checkBalance(payload)
        )
    )
    .doOnSubscribe(s -> System.out.println("subscribing"))
    .doOnSuccess((resp) -> {
        log.info("Check Balance got response success {}", resp.getUserID());
        log.debug("Check Balance got response success {}", resp.toString());
    })
    .doOnError(throwable -> {
        this.logError(throwable, "Check balance userid:" + payload);
    })
    .retry((retryCount, error) -> retryCount < 3)
    .toFuture();

Single.defer()的作用是每次订阅(包括重试触发的订阅)都会重新执行内部的代码块,这样每次重试都会生成新的带有效deadline的Stub,请求就能正常发到服务端了。

额外建议

  • 别啥错误都重试:当前代码对所有错误都重试3次,但像参数非法这种错误重试也没用,建议只对gRPC网络错误、服务端不可用这类可恢复的错误重试。
  • 加重试日志:在doOnError里打印当前重试次数和错误类型,方便确认重试是否真的触发,以及失败原因。

内容的提问来源于stack exchange,提问作者alok gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:57:39