如何解决获取超时 java.lang.IllegalStateException:阻止读取超时 5000000000 纳秒

How to resolve getting Timeout java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS

提问人:denisssj 提问时间:11/17/2023 更新时间:11/17/2023 访问量:37

问:

我想编写一个异步 api,在收到请求后返回 202 Accepted。然后,它应该每秒发送 n 个 Post 请求,以停止时间秒数。这是我对这个问题的尝试。

@PostMapping(value = "/stress")
@ResponseStatus(HttpStatus.ACCEPTED)
private Mono<?> stressPostLog(@RequestBody StressTest request) throws InterruptedException {
    return Mono.fromCallable(() -> {
            sendBatchRequest(request);
            return null;
    }).subscribeOn(Schedulers.boundedElastic());
    
}

private void sendBatchRequest(StressTest requestParams) throws InterruptedException {
    successfulRequest.set(0);

    long haltTimeMillis = requestParams.getHalt_time() * 1000;
    log.info("Halt Time Millis = " + haltTimeMillis );
    Integer count = 0;

    long initTime = System.currentTimeMillis();
    long currTime;
    do {
        Thread.sleep(1000); //! Sleep time is subjected to system
        for(int i = 0; i < requestParams.getRequest_per_second(); i++)
        {
            AuditSchema request = AuditSchema.generateRandomValue(requestParams.getRequest_size());
            Mono<?> response = postAndIncrement(request);
            response.publishOn(Schedulers.boundedElastic()).subscribe();
            count++;
        }
        currTime = System.currentTimeMillis();
        log.info("Time duration = " + ( currTime - initTime));
    }while((currTime - initTime) < haltTimeMillis);

    log.info("Request Send = {} and Response Succeed = {}", count, successfulRequest);
}

private Mono<?> postAndIncrement(AuditSchema request) {
    return this.client.post()
            .uri("v1/log")
            .body(BodyInserters.fromValue(request))
            .accept(MediaType.APPLICATION_JSON)
            .exchangeToMono(clientResponse -> {
                log.info("Request suceeded {}", clientResponse.statusCode());
                successfulRequest.getAndIncrement();
                return Mono.empty();
            });
}

但是,调用不是异步执行的,5 秒后它会因错误而终止

java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS

如何使用 spring webflux 编写此内容。

Java Spring 异步 spring-webflux

评论


答:

0赞 Rob Spoor 11/17/2023 #1

仅仅因为你使用并不意味着它是异步执行的。请改用:fromCallableCallablefromFuture

return Mono.fromFuture(CompletableFuture.runAsyc(() -> sendBatchRequest(request)))
        .subscribeOn(Schedulers.boundedElastic());

如果需要,您可以提供 (or ) 来代替使用公共分叉联接池。ExecutorExecutorServicerunAsync

评论

0赞 denisssj 11/17/2023
这并不能解决 202 在处理前未发布的问题,并且我仍然收到超时错误。
0赞 Rob Spoor 11/17/2023
你是对的,你可能需要将返回值与异步处理分离。由于您的方法返回 ,因此在 mono 完成时发送 HTTP 响应。试着返回,让单声道在后台工作。Monovoid