公司的rpc最早是采用Apache HttpComponents来做的,一个http请求即搞定,外加一些业务上的安全控制,倒也简单方便。由于异步的HttpComponents诞生较晚,后来改到了okhttp3.偶然的机会,突然想试一下RestTemplate。
1、restTemplate配置
2、ClientHttpRequestFactory配置
3、HttpMessageConverter配置的话按需配置
4、TestCase
5、requertFactory为okhttp3
6、requestFactory为netty4
从图上可以看到okhttp3和netty请求响应的时间差距还是非常大的,可以大家不是都是netty是高性能的吗?
为了找找原因,去翻翻代码看看代码到底是怎么处理的吧。
首先http request是如何创建的
该接口有如下实现:
第一个是apache httpConponent的实现,除了构建基本的信息以外没有什么特别的配置。
第二个是Netty4ClientHttpRequestFactory,类的开头有这么一行注释:
这个实现是每一次请求都会关联http connection。在HTTP/1.1里,就默认是开启了keep-alive,要关闭keep-alive需要在HTTP请求头里显示指定,即 keep-alive:on 或者keep-alive:close。现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。所以想要每次请求都重新创建连接也很简单,只需要将keep-alive设置为close即可。
找到了可能的原因那么我们就来看看netty创建http request是如何处理的。
nettyRequest.headers().set(HttpHeaders.CONNECTION, "close"); 即为设置connection为close。
因此,基本可以确定造成性能差异的原因为Netty4ClientHttpRequest将创建的request的header中keep-alive设置为close,每次请求都是短连接。
第三个实现为OkHttp3ClientHttpRequest,该实现只是将外部设定的请求头参数放到了http request的头部。
同时,通过使用其他客户端发现性能相差无几。在spring5版本中已经将Netty4ClientHttpRequest标记为弃用。