2020-10-29 11:03:32
浏览数 (1)
导读
- A平台在给其他平台推送数据时,A平台调用其他平台接口成功,但无返回结果,导致消费机数据不消费。
逻辑分析
- 应该有推送多长时间无返回结果就为推送失败,这样的逻辑。
代码分析
推送源码
代码语言:javascript
复制RestTemplate restTemplate = new RestTemplate();
ResponseResult responseResult = restTemplate.postForObject(syncUrl, formEntity, ResponseResult.class);
- 感觉restTemplate有配置,但是查看了RestTemplate类,并没有相关配置。经过百度发现:SimpleClientHttpRequestFactory类。
SimpleClientHttpRequestFactory 部分源码
代码语言:javascript
复制public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, AsyncClientHttpRequestFactory {
private static final int DEFAULT_CHUNK_SIZE = 4096;
private Proxy proxy;
private boolean bufferRequestBody = true;
private int chunkSize = 4096;
private int connectTimeout = -1;
private int readTimeout = -1;
private boolean outputStreaming = true;
private AsyncListenableTaskExecutor taskExecutor;
//...
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
//...
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
}
- 发现有 setConnectTimeout 和 setReadTimeout 方法,且默认值为 -1。进而猜测是这里导致一直卡死。
修改推送代码(方式一)
代码语言:javascript
复制SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(20000);
requestFactory.setReadTimeout(20000);
RestTemplate restTemplate = new RestTemplate(requestFactory);
思考
- 有没有配置文件可以进行配置,而不用每次set配置呢?
编写配置 RestTemplateConfiguration 类 (方式二)
代码语言:javascript
复制@Configuration
@ConditionalOnClass(value = {RestTemplate.class, HttpClient.class})
public class RestTemplateConfiguration {
@Value("${remote.maxTotalConnect:0}")
private int maxTotalConnect; //连接池的最大连接数默认为0
@Value("${remote.maxConnectPerRoute:200}")
private int maxConnectPerRoute; //单个主机的最大连接数
@Value("${remote.connectTimeout:2000}")
private int connectTimeout; //连接超时默认2s
@Value("${remote.readTimeout:30000}")
private int readTimeout; //读取超时默认30s
private ClientHttpRequestFactory createFactory() {
if (this.maxTotalConnect <= 0) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(this.connectTimeout);
factory.setReadTimeout(this.readTimeout);
return factory;
}
HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect)
.setMaxConnPerRoute(this.maxConnectPerRoute).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
httpClient);
factory.setConnectTimeout(this.connectTimeout);
factory.setReadTimeout(this.readTimeout);
return factory;
}
@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate(this.createFactory());
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
HttpMessageConverter<?> converterTarget = null;
for (HttpMessageConverter<?> item : converterList) {
if (StringHttpMessageConverter.class == item.getClass()) {
converterTarget = item;
break;
}
}
if (null != converterTarget) {
converterList.remove(converterTarget);
}
converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
converterList.add(new FastJsonHttpMessageConverter4());
return restTemplate;
}
}
该配置文件的使用
代码语言:javascript
复制@Service
@Import({RestTemplateConfiguration.class})
public class AServiceImpl implements AService {
private final ADao aDao;
//...
}