首页 > 解决方案 > RestTemplate.postForObject() java.net.SocketTimeoutException: 读取超时即使成功

问题描述

我在同一台服务器上有两个 Java Spring Boot Web 服务应用程序通过 REST 相互调用。服务 A 调用服务 B,后者根据通知成功执行操作。问题是服务 A 从来没有收到服务 B 的确认,所以它认为它已经失败了,并且根据它的循环恢复逻辑,它再次尝试……一次又一次……一次又一次。服务 B 最终做了 3 倍的工作而没有额外的好处。

相关代码(为保护有罪而删减和篡改)如下:

服务一:

public void giveOrderToServiceB(@RequestBody CustomClass message) {
...    
org.springframework.web.client.RestTemplate template = new RestTemplate(clientHttpRequestFactory());
com.mycompany.CustomReply reply = template.postForObject(serviceBUrl, message, CustomReply.class);

服务 B REST 控制器:

@PostMapping(value="ExecuteTheWork", produces=org.springframework.http.MediaType.APPLICATION_JSON_VALUE, consumes=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody CustomReply executeTheWork(@RequestBody CustomClass thing) {
    // do something with the thing...
   CustomReply reply = new CustomReply();
    reply.setReply("Successfully executed the work.");
    return reply;
}

调用 RestTemplate.postForObject() 后服务 A 捕获的实际异常是

java.net.SocketTimeoutException: Read timed out

请指教。

标签: restweb-servicesspring-bootsocket-timeout-exception

解决方案


好的,我想我明白了。在方法完成所有工作之前,我不会从服务 B 发回响应,这可能需要几秒钟到几分钟的时间。如果我立即回答(并跳过处理),它会始终如一地工作。需要将实际工作分拆到单独的线程。干杯


推荐阅读