restTemplate 针对IO密集型的需要优化请求数

package com.michaels.configuration;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.pool.PoolStats;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.Duration;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Configuration
public class RestTemplateConfig {
  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setRequestFactory(clientHttpRequestFactory());
    return restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(15))
            .setReadTimeout(Duration.ofSeconds(15))
            .build();
  }

  @Bean
  public RestTemplate longTimeoutRestTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(60))
            .setReadTimeout(Duration.ofSeconds(60))
            .build();
  }

  public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {

    try {
      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
      SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
        public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
          return true;
        }
      }).build();
      httpClientBuilder.setSSLContext(sslContext);
      HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
      SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,hostnameVerifier);
      Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
              .register("http", PlainConnectionSocketFactory.getSocketFactory())
              .register("https", sslConnectionSocketFactory).build();// 注册http和https请求
      // 开始设置连接池
      PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
      poolingHttpClientConnectionManager.setMaxTotal(2000); // 最大连接数2700
      poolingHttpClientConnectionManager.closeExpiredConnections();
      poolingHttpClientConnectionManager.setDefaultMaxPerRoute(1000); // 同路由并发数100
      httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
      httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)); // 重试次数
      HttpClient httpClient = httpClientBuilder.build();
      HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // httpClient连接配置
      clientHttpRequestFactory.setConnectTimeout(10000); // 连接超时
      clientHttpRequestFactory.setReadTimeout(6000); // 数据读取超时时间
      clientHttpRequestFactory.setConnectionRequestTimeout(20000); // 连接不够用的等待时间
      printLeased(poolingHttpClientConnectionManager);//打印http阻塞数量
      return clientHttpRequestFactory;
    } catch (Exception e) {
      log.error("初始化HTTP连接池出错"+e.toString());
    }
    return null;

  }


  private void printLeased(PoolingHttpClientConnectionManager manager){
    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
    scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        Set<HttpRoute> routes = manager.getRoutes();
        Iterator<HttpRoute> iterator = routes.iterator();
        while (iterator.hasNext()){
          HttpRoute next = iterator.next();
          if(next!=null){
            PoolStats stats = manager.getStats(next);
            log.error(next.toString()+"---最大并发数---"+stats.getMax()+"=剩余请求数---------"+stats.getLeased()+"------"+stats.getPending());
          }
        }
      }
    },1,1, TimeUnit.SECONDS);
  }

}

SpringBoot 配置

http:
  pool:
    connectionRequestTimeout: 3000
    connectTimeout: 6000
    socketTimeout: 10000
    validateAfterInactivity: 2000
    maxTotal: 300
    maxPerRoute: 100
    idleKeepDuration: 20000
    evictIdleDuration: 2000
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值