提问人:denisssj 提问时间:11/17/2023 更新时间:11/17/2023 访问量:37
如何解决获取超时 java.lang.IllegalStateException:阻止读取超时 5000000000 纳秒
How to resolve getting Timeout java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS
问:
我想编写一个异步 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 编写此内容。
答:
0赞
Rob Spoor
11/17/2023
#1
仅仅因为你使用并不意味着它是异步执行的。请改用:fromCallable
Callable
fromFuture
return Mono.fromFuture(CompletableFuture.runAsyc(() -> sendBatchRequest(request)))
.subscribeOn(Schedulers.boundedElastic());
如果需要,您可以提供 (or ) 来代替使用公共分叉联接池。Executor
ExecutorService
runAsync
评论
0赞
denisssj
11/17/2023
这并不能解决 202 在处理前未发布的问题,并且我仍然收到超时错误。
0赞
Rob Spoor
11/17/2023
你是对的,你可能需要将返回值与异步处理分离。由于您的方法返回 ,因此在 mono 完成时发送 HTTP 响应。试着返回,让单声道在后台工作。Mono
void
评论