我在同一台服务器上有两个Java Spring Boot web服务应用程序,它们通过REST相互调用。服务A调用服务B,后者成功地执行了通知。问题是,服务A从未收到服务B的确认,因此它认为自己失败了,根据其循环恢复逻辑,它会一次又一次地尝试。服务B最终做了3倍的工作,没有任何额外的好处。
相关代码(为了保护罪犯而被剥离和伪造(如下:
服务A:
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);
Service 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;
}
服务A在调用RestTemplate.postForObject((后捕获的实际异常是
java.net.SocketTimeoutException: Read timed out
请告知。
好吧,我想我得到了。在方法完成所有工作之前,我不会从服务B发回响应,这可能需要几秒钟到几分钟的时间。如果我立即回答(并跳过处理(,它会一直工作。需要将实际工作拆分为一个单独的线程。奶酪
当您在应用程序中注册rest模板的bean时,它必须在超时的情况下对其进行配置。以下是Spring应用程序配置文件
package com.temp.project.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class TempProjectConfig {
/**
* Set Timeout for HTTP requests
* @return
*/
@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 1200000; // here is the timeout property set for rest template
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
= new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return clientHttpRequestFactory;
}
/**
* RestTemplate to call REST endpoints
* @param clientHttpRequestFactory
* @return
*/
@Bean
public RestTemplate getRestTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
return new RestTemplate(clientHttpRequestFactory);
}
}