记录RestTemplate一个本身挖的坑

  • 前言

就在昨天线上的X服务调用的Y服务须要上线,而后Y服务的ng路由作了改动。而后A服务的RestTemplate调用Y服务的某个接口开始报400!服务器

刚刚开始咱们觉得是ng路由配置的问题,由于咱们X服务并无作上线,以前也运行平稳,因此咱们就下意识的认为应该是Ng配置的缘由。可是当Ng配置还原以后,问题并无解决,仍旧是400!并发

而后咱们直接在X服务器上用curl访问Y服务的接口,访问正常!因此排除X服务问题,那么只有多是X服务出问题。可是X服务一直并无作上线呀,为何ng作了改动就这样了呢!curl

后面一直没找到问题,无奈之下重启了服务,问题再也不出现!高并发

  • 思考

整个自个人测试流程下来,其实基本能够定位到是A服务的问题,虽然他并无作改动,可是确定是外部的环境致使了A服务某个地方出现了问题。随后,咱们定位到了RestTemplate这个点!性能

疯狂找问题中。。。。测试

loading。。。。ui

最后发现咱们是将RestTemplate设置成了单例,而后初始化的时候用了HttpComponentsClientHttpRequestFactory。用这个是为了配置RestTemplate调用的时候的超时配置。编码

这个时候问题就来了!url

HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();

因为我是这样实例化HttpComponentsClientHttpRequestFactory,能够看到源码是:3d

由图可知HttpComponentsClientHttpRequestFactory默认用的是HttpClient,而后他的一个构建工厂HttpClientBuilder有一个属性是systemProperties。再看下面的源码:

systemProperties这个属性为true的时候,HttpClient保持长链接了,并且接下去他会使用默认一个重用策略DefaultClientConnectionReuseStrategy。。。

坑爹啊,留下悔恨的眼泪。。。。

  • 定位

因此也就是说当我使用默认的初始化HttpComponentsClientHttpRequestFactory的时候,他默认会使用HttpClient的长链接。此时若是一旦出现调不通的状况,长链接在超时的时间内还会一直保持着链接,并且还会复用上一次错误的链接信息。所以咱们才会后续一直是400的状况,到咱们重启以后,长链接所有重置,又恢复如初。

  • 解决

因此解决这个问题只要在初始化HttpComponentsClientHttpRequestFactory的时候,传入自定义的HttpClient来实例HttpComponentsClientHttpRequestFactory,这样他就不会默认使用HttpClient的长链接,问题便可解决!

HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

同时记得配置HttpClient最大链接数以及同路由并发数,防止高并发的时候RestTemplate的性能!

// 开始设置链接池
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
// 最大链接数
poolingHttpClientConnectionManager.setMaxTotal(maxTotal);
// 同路由并发数
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(maxPerRoute);、
  • 总结

当编码的时候,必定要思考详细,注意细节,要多看源码!不要想固然的直接引用公共的方法或类,当使用的时候应该看看源码,了解他的原理,是怎么运行的,必要的配置是否配齐!

同时加入详细全面的测试,如果详细的自测,这个问题也是会显露出来的!

今天记录下来这个问题,时刻勉励本身,细节必决定成败!

相关文章
相关标签/搜索