spring RestTemplate使用说明

rest-template是spring对httpclient的逻辑封装,它底层还是基于httpclient,所以一些配置其实跟httpclient是强相关的。

基本配置

rest-template可以不带参数,使用默认配置,也可以指定ClientHttpRequestFactory参数,ClientHttpRequestFactory是一个interface,其具体实现有:

  • HttpComponentsClientHttpRequestFactory,包含一个apache的HttpClient实例
  • OkHttp3ClientHttpRequestFactory,包含一个OkHttpClient的实例

以HttpComponentsClientHttpRequestFactory为例,它接受一个apache的HttpClient实例,我们可以定制其配置,样例代码如下:

return HttpClients.custom()
            .setMaxConnTotal(10000)  // 连接池的最大连接数
            .evictIdleConnections(10, TimeUnit.MINUTES) // 连接池内的连接空闲超出该时间即销毁
            .setConnectionTimeToLive(15, TimeUnit.MINUTES) //连接在15分钟后过期,默认-1表示永不过期
            .evictExpiredConnections() //启动过期连接的检测线程,勿漏掉!
            .setMaxConnPerRoute(2000)  //单域名允许的最大连接数
            .setDefaultRequestConfig(buildRequestConfig()) // 连接配置见下
            .setRetryHandler(new DefaultHttpRequestRetryHandler(2, true)) //失败后重试次数;重试时是否需要重新发送请求
            .build();

RequestConfig属于基本的连接配置,如下:

return RequestConfig.custom()
            .setConnectTimeout(5) // TCP连接超时
            .setConnectionRequestTimeout(60) //从连接池获取连接的超时
            .setSocketTimeout(60) // 请求等待超时
            .build();

顺带说一下一个TCP连接耗费的内存数(参考这里),使用

sysctl -A | grep net | grep mem

命令可以查看一个TCP连接的读写缓存默认大小,在我的ubuntu上大约200~300K,注意只是默认大小,随着连接数增大,读写缓存大小是会降低的。像上面的例子,若10000个连接都是忙碌的,内存应该会达到G级别(实际则不会,总有部分连接是空闲的)。

连接有效性问题

我们在spring后台开发里一般用的长连接去访问三方服务,这样可避免TCP握手的开销。长连接是可复用的,一般用连接池管理,像apache httpclient里就有一个连接池管理类:PoolingHttpClientConnectionManager。
当我们在代码里关闭一个连接时,该连接并不真的释放,而是被放回连接池里。下次有请求到来,该连接会被取出再次使用。那么,我们如何保证再次取出的连接是有效的呢?
apache httpclient提供了2个选项:

  • 设置TTL(timeToLive),对应上一节的setConnectionTimeToLive
  • 空闲连接清理,对应上一节的evictIdleConnections

apache httpclient会起一个单独的线程去检查连接池里的连接是否过期,相应的机制在IdleConnectionEvictor里,检测线程会分别检查每个连接的TTL和空闲时间,及时将连接池里的无效连接清理掉。
但上述机制并非100%可靠,现网情况千奇百怪,总有例外情形,所以使用连接池必须要配置retry机制,否则网络故障、限流等都可能造成无效连接,在无效连接上发送或接收数据,都会报connection reset错误。
关于连接池的具体分析,可参考我的另一篇文章:
https://blog.youkuaiyun.com/tlxamulet/article/details/146562844?spm=1011.2415.3001.5331

安全配置

httpclient需指定SSLContext,所谓SSLContext,就是对接的SSL协议,像SSLv2、SSLv3、TLSv1、TLSv1.1、TLSv1.2、TLSv1.3等,它规定了握手和数据加密传输的一套安全算法,最新最安全的是TLSv1.3,当前多数浏览器和服务器都支持了,不过TLSv1.2还在广泛使用。

生成一个最简单的SSLContext的代码样例:

X509TrustManager x509TrustManager = new X509TrustManagerImpl();
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new X509TrustManager[] {x509TrustManager}, randomInstance);
return sslContext;

这里,X509TrustManagerImpl可以是一个空实现,不对client和server证书做任何校验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值