背景:最近工作上搭建了一个中间系统,采用了RestTemplate框架调用第三系统restful接口,调用方采用轮询的方式调用本系统的相关接口,期间多次出现堆内存溢出,系统假死,通用java自带的java内存分析工具分析系统生成的dump文件发现有一对象一直没被回收,占用98%堆内存,使用MAT分析该对象所在的线程,发现是使用resttemplate的相关线程,及相关的线程产生的堆对象并没有随resttemplate的close后被清除掉,网上搜索相关资料显示,传统HttpClient 在高请求量和高并发情况,很容易出现堆内存溢出的情况,而使用Apache中的HttpClient的实例CloseableHttpClient很少发生该现象,而RestTemplate默认使用的是org.springframework.http.client.ClientHttpRequest,需在配置文件进行相关的替换;

本文主要记录springboot中配置RestTemplate。

1、添加依赖:

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version>
</dependency>

2、配置CloseableHttpClient向相关属性,并设置定时清理连接

Package com.**.config;import lombok.extern.slf4j.Slf4j;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.connectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.comn.ssl.TrustSelfsignedStrategy;
import org.apache.http.Impl.client.CloseableHttpClient;
import org.apache.http.Impl.client.Httpclients;
import org.apache.http.Impl.conn.PoolingHttpclientConnectionManager;
import org.apache.http.Message.BasicHeaderELementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;/* * * Supports both HTTP and HTTPS* Uses a connect ion pool to re-use connect ions and save overhead of creat ing connect ions.* Has a custom connection keep-al ive strategy  (to apply a default keep-alive if one isn't specified)* starts an idle connection monitor to cont inuously clean up stale connections.*/
@Slf4j
@Configuration
public class HttpClientConfig {//Determines the timeout in milliseconds until a  connection is established.private static final int CONNECT_TIMEOUT = 30000;//The  timeout when requesting a connection from the connection manager.private static final int REQUEST_ TIMEOUT = 30000;//The timeout for waiting for dataprivate static final int SOCKET_ TIMEOUT = 60000;private static final int MAX_ TOTAL CONNECTIONS = 50;private static final int DEFAULT KEEP ALIVE_ TIME_ MIlLIS = 20 * 1000;private static final int CLOSE_ IDLE_ CONNECTION WAIT_ TIME_ SECS = 30;@Beanpublic PoolingHttpClientConnectionManager poolingConnectionManager() {SSLContextBuilder builder = new SSLContextBuilder ();try {builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());}catch (NoSuchAlgorithmException | KeyStoreException e) {log.error ("Pooling Connection Manager Initialisation failure because of"+ e.getMessage(), e);}SSLConnectionSocketFactory sslsf = null;try{sslsf = new SSLConnectionSocketFactory (builder.build());} catch (KeyManagementException | NoSuchAlgorithmException e) {log.error("Pooling Connection Manager Initialisation failure because of" + e.GetMessage(), e);}Registry <ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.create ().register ("https", sslsf).register (id: "http", new PlainConnectionSocketFactory ()).build ();PoolingHttpclientConnectionManager poolingConnectionManager = new PoolingHttpclientConnectionManager  (socketFactoryRegistry);poolingConnectionManager.setMaxTotal(MAX_ TOTAL CONNECTIONS);return poolingConnectionManager;}@Beanpublic ConnectionKeepAliveStrategy connectionKeepAliveStrategy () {return new ConnectionKeepAliveStrategy (){@overridepublic long getKeepAliveDuration (HttpResponse response, HttpContext context) {HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));while (it.hasNext()) {HeaderElement he = it.nextElement();String param = he.getName();String value = he.getValue();if (value != null && param.equalsIgnoreCase("timeout")) {return Long.parseLong(value) * 1000;}}return DEFAULT_ KEEP_ALIVE_TIME_MILlIS;}};}@Beanpublic CloseableHttpClient httpClient () {RequestConfig requestConfig = RequestConfig.custom ().setConnectionRequestTimeout(REQUEST_TIMEOUT).setConnectTimeout (CONNECT_TIMEOUT).setSocketTimeout (SOCKET_TIMEOUT).build();return Httpclients.custom ().setDefaultRequestConfig(requestConfig).setConnectionManager (poolingConnectionManager ()).setKeepAliveStrategy (connectionKeepAliveStrategy ()).build ();}@Beanpublic Runnable idleConnectionMonitor (final PoolingHttpClientConnectionManager connectionManager){return new Runnable() {@override@Scheduled(fixedDelay = 10000)public void run() {try {if (connectionManager != null) {log.trace("run IdleConnectionMonitor - Closing expired and idle connections... ");connectionManager.closeExpiredConnections();connectionManager.closeIdleConnections(CLOSE_IDLE_CONNECTION_WAIT_TIME_SECS, TimeUnit.SECONDS);} elselog.info("run IdleConnectionMonitor - Http Client Connection manager is not initialised");} catch (Exception e) {log.error("run IdleConnectionMonitor - Exception occurred.msg={}. ", e.getMessage());}}};}
}

3、替换RestTemplate中的默认httpClient

Package com.**.config;import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.Httpcomponentsclienthttprequestfactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;@Slf4j
@Configuration
public class RestTemplateConfig {@AutowiredCloseableHttpClient httpClient;@Beanpublic RestTemplate restTemplate () {RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());/*** StringHttpMessogeConverter 默认使用 IS0-8859-编码,此处修改为 UTF-8*/List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();while (iterator.hasNext()) {HttpMessageConverter<?> converter = iterator.next();if (converter instanceof StringHttpMessageConverter) {((StringHttpMessageConverter) converter).setDefaultCharset(Charset.forName("UTF-8"));}}return restTemplate;}@Beanpublic HttpComponentsClientHttpRequestFactory clientHttpRequestfactory () {HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =  new HttpComponentsClientHttpRequestfactory();clientJttpRequestFactory.setHttpClient(httpClient);return clientHttpRequestFactory;}@Beanpublic TaskScheduler taskScheduler() {ThreadPooolTaskScheduler scheduler = new ThreadPooolTaskScheduler();scheduler.setThreadNamePrefix("poolScheduler");scheduler.setPoolSize (50);return scheduler;}
}

4、在启动类中注入RestTemplate类:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){return builder.build();
}

至此,RestTemplate就可以正常使用了。

参考资料:https://www.cnblogs.com/jimw/p/9037542.html

转载于:https://www.cnblogs.com/gdwkong/p/9538594.html

SpingBoot —— RestTemplate的配置相关推荐

  1. SpringCloud Sentinel 使用restTemplate的两种配置介绍

    @SentinelResource 主要属性介绍 value:自定义的资源名称.不设置默认为当前类全名.方法名. blockHandler:降级的处理方法名,默认在当前类中匹配.如果指定了blockH ...

  2. java rest 调用_Java调用Restful之RestTemplate

    1.spring-mvc.xml中增加RestTemplate的配置 2.引入相关jar包 httpclient-4.3.3.jar.httpcore-4.3.2.jar,jar包版本根据需求自行调整 ...

  3. springboot集成restTemplate实现rest接口调用

    目录 一restTemplate简介 二restTemplate常用方法列表 2.1 get请求方法预览 2.2 post方法请求预览 2.3put请求方法预览 2.4 delete请求方法预览 2. ...

  4. HttpClient、OKhttp、RestTemplate对比

    一.三者的对比 HttpClient:代码复杂,还得操心资源回收等.代码很复杂,冗余代码多,不建议直接使用. RestTemplate: 是 Spring 提供的用于访问Rest服务的客户端, Res ...

  5. 使用RestTemplate访问restful服务时遇到的问题

    可以通过通过wireshark抓包,使用Postman发送请求 wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示网络封包的详细信息.使用wireshark的人必 ...

  6. restTemplate踩过的坑-spring clound--cloud内部服务调用重试次数

    转载自 https://www.cnblogs.com/jimw/p/9037542.html 现在公司项目基本都从臃肿的项目转换成微服务的方向转换,因此也从中使用了spring clound的一些组 ...

  7. 使用RestTemplate时报错java.lang.IllegalStateException: No instances available for 127.0.0.1

    我在RestTemplate的配置类里使用了 @LoadBalanced @Component public class RestTemplateConfig { @Bean @LoadBalance ...

  8. RestTemplate实践

    一.RestTemplate是什么 环境约束: spring-web-4.3.9.RELEASE Spring文档: https://docs.spring.io/spring/docs/4.3.9. ...

  9. Spring Cloud 微服务实战系列-Ribbon整合RestTemplate实现负载均衡

    导语   在Spring Cloud项目中想要整合Ribbon只需要在pom文件中加入对应的依赖就可以了,那么在这次的分享中就来看看在Ribbon怎么通过RestTemplate来进行负载均衡,以及扩 ...

  10. Spring Boot RestTemplate 忽略证书访问https

    在Spring Boot中,RestTemplate 一般使用 @Autowired 注解自动装配, 类似: @Autowiredprivate RestTemplate restTemplate; ...

最新文章

  1. SQL Server 行转列,列转行
  2. 将字符串型转换为整形
  3. linux内核和w,Linux内核中Makefile、Kconfig和.config的关系
  4. android 百度移动搜索 url 参数,百度刷站内快排算法参数-百度搜索URL参数比较详解...
  5. Spring系列(十):@Autowired 和@Resource注解用法介绍
  6. 技术人写作和写代码一样重要
  7. OpenTSDB 开发指南之 Api操作数据
  8. 机房布线的最高境界 | 最后的暗黑系,真是亮瞎眼 ​
  9. [转]Newtonsoft.Json高级用法
  10. CF1110G Tree-Tac-Toe 博弈论、构造
  11. 函数和存储过程的区别
  12. 神经网络是不是分类算法,人工神经网络分类算法
  13. (L)小写l和(i)大写I的区分方法
  14. 游戏音效制作初学者的福音—入门级软件介绍
  15. 思睿普信息IT技术服说明
  16. 博思特POSITAL编码器OCD58-CA1212-B15V-H3P
  17. 计算机与人脑pdf_我们距离将人脑复制到计算机有多远
  18. yolov5在plotting labels时停止并显示Process finished with exit code 1
  19. 微信小程序与web前端的区别
  20. php需要学习什么,学好php需要掌握什么

热门文章

  1. java案例代码17--正则表达式小案例
  2. 为计算机构建安全方案,计算机科学系安全管理标准化建设实施方案
  3. 无法更新标识列 wechatid_天津塘沽企业标识标牌设计制作安装的过程
  4. 用c#转换word或excel文档为html文件,C#实现DataSet内数据转化为Excel和Word文件的通用类完整实例...
  5. PostgreSQL高级扩展之IP4R
  6. 树莓派(Raspberry Pi)日期时间不准的修正方法
  7. 线程并行化的概念及其用法
  8. 打log的方式检查程序里面的问题 及示例代码 详解
  9. iPhone6分辨率
  10. backtrack常用的一些综合扫描工具实例用法