java实用型

网友投稿 302 2022-09-20


java实用型

目录前言一、RestTemplate是什么?二、如何使用1.创建一个bean2.使用步骤三、高并发下的RestTemplate使用1.设置预热功能2.合理设置maxtotal数量总结

前言

如果java项目里有调用第三方的http接口,我们可以使用RestTemplate去远程访问。也支持配置连接超时和响应超时,还可以配置各种长连接策略,也可以支持长连接预热,在高并发下,合理的配置使用能够有效提高第三方接口响应时间。

一、RestTemplate是什么?

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

二、如何使用

1.创建一个bean

以下代码配置比较简单,只设置了连接超时时间和响应超时时间

/**

* restTemplate配置

*

* @author Songsong

* @date 2020-08http://-17 15:09

*/

@Configuration

public class RestTemplateConfiguration {

@Bean(name = "restTemplate")

public RestTemplate restTemplate() {

SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();

//设置连接超时时间1s

factory.setConnectTimeout(1000);

//设置读取时间1s

factory.setReadTimeout(1000);

return new RestTemplate(factory);

}

}

2.使用步骤

在需要使用的地方使用@Resource或者@Autowired注入进来

@Resource

private RestTemplate restTemplate;

然后我们平常调用第三方的接口是get方式和post方式,restTemplate提供getForEntity和postForEntity方法支持这两种方式,直接调用即可,源码分别如下:

getForEntity方法:

public ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables) throws RestClientException {

RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);

ResponseExtractor> responseExtractor = this.responseEntityExtractor(responseType);

return (ResponseEntity)nonNull(this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));

}

postForEntity方法:

public ResponseEntity postForEntity(String url,http:// @Nullable Object request, Class responseType, Object... uriVariables) throws RestClientException {

RequestCallback requestCallback = this.httpEntityCallback(request, responseType);

ResponseExtractor> responseExtractor = this.responseEntityExtractor(responseType);

return (ResponseEntity)nonNull(this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));

}

只需要解析返回的参数即可。

三、高并发下的RestTemplate使用

在平常的开发中,以上简单的配置可能就够用了,但是在高并发下,对接口响应时间要求很高,所以我们需要尽量的提高第三方接口响应时间。在RestTemplate中可以使用httpClient长连接,关于httpClient长连接的介绍我们可以参考:HTTPclient保持长连接

以下代码我们设置了长连接预热的功能,以及路由并发数:

@Slf4j

@Configuration

public class RestTemplateConfiguration {

@Bean(name = "restTemplate")

public RestTemplate restTemplate() {

return getRestTemplate(3, "https://baidu.com/......");

}

private RestTemplate getRestTemplate(int maxTotal, String preHeatUrl) {

HttpComponentsClientHttpRequestFactory httpRequestFactory = httpComponentsClientHttpRequestFactory(maxTotal);

RestTemplate restTemplate = new RestTemplate(httpRequestFactory);

//解决首次预热耗时长

if (StringUtils.isNotEmpty(preHeatUrl)) {

try {

restTemplate.postForEntity(preHeatUrl, "", String.class);

} catch (Exception e) {

log.error("preHeat url error:{}", e.getMessage());

}

}

return restTemplate;

}

/**

* ClientHttpRequestFactory接口的另一种实现方式(推荐使用),即:

* HttpComponentsClientHttpRequestFactory:底层使用Httpclient连接池的方式创建Http连接请求

*

* @return

*/

private HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(int maxTotal) {

//Httpclient连接池,长连接保持时间

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(1, TimeUnit.HOURS);

//设置总连接数

connectionManager.setMaxTotal(maxTotal);

//设置同路由的并发数

connectionManager.setDefaultMaxPerRoute(maxTotal);

//设置header

List

headers = new ArrayList
();

headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));

headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));

headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));

headers.add(new BasicHeader("Connection", "keep-alive"));

//创建HttpClient

HttpClient httpClient = HttpClientBuilder.create()

.setConnectionManager(connectionManager)

.setDefaultHeaders(headers)

.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //设置重试次数

.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //设置保持长连接

.build();

//创建HttpComponentsClientHttpRequestFactory实例

HttpComponentsClientHttpRequestFactory requestFactory =

new HttpComponentsClientHttpRequestFactory(httpClient);

//设置客户端和服务端建立连接的超时时间

requestFactory.setConnectTimeout(10000);

//设置客户端从服务端读取数据的超时时间

requestFactory.setReadTimeout(5000);

//设置从连接池获取连接的超时时间,不宜过长

requestFactory.setConnectionRequestTimeout(2000);

//缓冲请求数据,默认为true。通过POST或者PUT大量发送数据时,建议将此更改为false,以免耗尽内存

requestFactory.setBufferRequestBody(false);

return requestFactory;

}

1.设置预热功能

我们可以看到,在getRestTemplate方法中,

return restTemplate;

之前先请求了一次,也就是说在需要使用第三方接口调用的service层注入的时候,提前先调用了一次,根据长连接的特性,一般第一次连接的时间较长,使用完之后,这个连接并不会马上回收掉,在一定的时间还是存活状态,所以在高并发下,经过预热后的接口响应时间会大幅提高。

2.合理设置maxtotal数量

我们可以看到以下代码

//设置总连接数

connectionManager.setMaxTotal(maxTotal);

我们可以看到这一行,maxTotal是设置总连接数,这个设置需要根据接口的响应时间以及需要支持的QPS来设置,比如接口响应时间是100ms,需要支持的QPS为5000,也就是5000/s,那么一个长连接1s就是能够处理10个请求,那么总共需要maxTotal为500个,这个就是设置的大概数量,但是有时候QPS不是那么稳定,所以具体设置多少得视具体情况而定。

RestTemplate深度解析可以参考:RestTemplate深度解析

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Elasticsearch 权威指南学习笔记】查询语句提升权重(elasticsearch面试)
下一篇:【Elasticsearch 权威指南学习笔记】使用布尔bool匹配(elasticsearch收费吗)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~