1、引入maven依赖
<!-- httpclient - httpasyncclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore-nio -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-nio</artifactId>
<version>4.4.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore-nio -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-nio</artifactId>
<version>4.4.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpasyncclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.4</version>
</dependency>
2、创建帮助类
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@Slf4j
public class HttpAsynClient {
/**
* 连接超时,连接建立时间,三次握手完成时间
*/
private static int socketTimeout = 100000;
/**
* 请求超时,数据传输过程中数据包之间间隔的最大时间
*/
private static int connectTimeout = 100000;
/**
* 使用连接池来管理连接,从连接池获取连接的超时时间,0不超时
*/
private static int connectionRequestTimeout = 200000;
/**
* 连接池最大连接数
*/
private static int poolSize = 100;
/**
* 每个主机的并发最多10
*/
private static int maxPerRoute = 20;
/**
* 创建非异步的可关闭的且跳过https 验证的 httpClient
*
* @return
*/
public static CloseableHttpClient createSSLClientDefault() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
log.error(e.getMessage(), e);
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
} catch (KeyStoreException e) {
log.error(e.getMessage(), e);
}
return HttpClients.createDefault();
}
/**
* 创建异步的可关闭的跳过https验证的 httpClient对象
*
* @param connManager 连接管理器 可以调用本类的getConnManager 生成
* @return
*/
public static CloseableHttpAsyncClient getClient(PoolingNHttpClientConnectionManager connManager) {
if (null == connManager) {
return null;
}
// 设置连接参数
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(HttpAsynClient.socketTimeout)
.setConnectTimeout(HttpAsynClient.connectTimeout)
.setConnectionRequestTimeout(HttpAsynClient.connectionRequestTimeout)
.build();
// 创建自定义的httpclient对象
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connManager)
.disableCookieManagement()
.build()) {
return httpclient;
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* 创建异步的可关闭的跳过https验证的 httpClient对象(绑定本地网卡)
*
* @param connManager
* @param localAddress
* @return
* @throws
*/
public static CloseableHttpAsyncClient getClient(PoolingNHttpClientConnectionManager connManager, String localAddress) throws UnknownHostException {
if (null == connManager || null == localAddress) {
return null;
}
String[] ipStrArr = localAddress.split("\\.");
if (ipStrArr.length != 4) {
return null;
}
byte[] ip = new byte[]{(byte) (Integer.parseInt(ipStrArr[0])), (byte) (Integer.parseInt(ipStrArr[1])), (byte) (Integer.parseInt(ipStrArr[2])), (byte) (Integer.parseInt(ipStrArr[3]))};
// 设置连接参数
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(HttpAsynClient.socketTimeout)
.setConnectTimeout(HttpAsynClient.connectTimeout)
.setConnectionRequestTimeout(HttpAsynClient.connectionRequestTimeout)
.setLocalAddress(InetAddress.getByAddress(ip))
.build();
// 创建自定义的httpclient对象
try (CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connManager)
.disableCookieManagement()
.build()) {
return client;
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* 初始化 连接管理器
*
* @return
*/
public static PoolingNHttpClientConnectionManager getConnManager() {
try {
// 绕过证书验证,处理https请求
SSLContext sslcontext = createIgnoreVerifySSL();
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder
.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", new SSLIOSessionStrategy(sslcontext, new AllowAllHostnameVerifier()))
.build();
// Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder
// .<SchemeIOSessionStrategy>create()
// .register("http", NoopIOSessionStrategy.INSTANCE)
// .register("https", new SSLIOSessionStrategy(sslcontext))
// .build();
// 配置io线程
IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setConnectTimeout(HttpAsynClient.socketTimeout)
.setSoTimeout(HttpAsynClient.connectTimeout)
.build();
// 设置连接池大小
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry);
connManager.setDefaultMaxPerRoute(maxPerRoute);
connManager.setMaxTotal(poolSize);
return connManager;
} catch (IOReactorException e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* 绕过验证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() {
SSLContext sc = null;
try {
sc = SSLContext.getInstance("TLS");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) {
}
@Override
public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
} catch (KeyManagementException e) {
log.error(e.getMessage(), e);
}
return sc;
}
/**
* 从 request请求对象 中获取ip地址
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
if (request == null) {
return null;
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
3、初始化连接池
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class AsynHttpClientFactory {
private static CloseableHttpAsyncClient httpclient;
private PoolingNHttpClientConnectionManager connManager;
public AsynHttpClientFactory() {
connManager = HttpAsynClient.getConnManager();
httpclient = HttpAsynClient.getClient(connManager);
httpclient.start();
log.info("异步httpClient启动完成...");
}
public static CloseableHttpAsyncClient getCloseableHttpAsyncClient() {
if (!httpclient.isRunning()) {
new AsynHttpClientFactory();
}
return httpclient;
}
}
4、创建调用帮助类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import java.io.StringWriter;
import java.util.Map;
import java.util.concurrent.Future;
@Slf4j
public class HttpAsynClientUtils {
/**
* get 请求
*
* @param url 地址
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO get(String url) throws Exception {
return get(url, null);
}
/**
* get 请求
*
* @param url 地址
* @param header 头部信息
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO get(String url, Map<String, String> header) throws Exception {
return get(url, header, null);
}
/**
* get 请求
*
* @param url 地址
* @param header 头部信息
* @param callback 回调方法
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO get(String url, Map<String, String> header, FutureCallback callback) throws Exception {
CloseableHttpAsyncClient httpClient = AsynHttpClientFactory.getCloseableHttpAsyncClient();
HttpGet httpGet = new HttpGet(url);
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpGet.addHeader(entry.getKey(), entry.getValue());
}
}
HttpResponseBO responseBO = new HttpResponseBO();
Future<HttpResponse> future = httpClient.execute(httpGet, callback);
try {
HttpResponse response = future.get();
StringWriter stringWriter = new StringWriter();
if (response.getEntity() != null) {
IOUtils.copy(response.getEntity().getContent(), stringWriter, "UTF8");
}
responseBO.setCode(response.getStatusLine().getStatusCode());
responseBO.setContent(stringWriter.toString());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
httpGet.releaseConnection();
return responseBO;
}
}
/**
* post 请求
*
* @param url 地址
* @param body body参数
* @param contentType 请求类型
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO post(String url, String body, ContentType contentType) throws Exception {
return post(url, body, null, contentType);
}
/**
* post 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param contentType 请求类型
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO post(String url, String body, Map<String, String> header, ContentType contentType) throws Exception {
return post(url, body, header, contentType, null);
}
/**
* post 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param contentType 请求类型
* @param callback 回调方法
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO post(String url, String body, Map<String, String> header, ContentType contentType, FutureCallback callback) throws Exception {
CloseableHttpAsyncClient httpClient = AsynHttpClientFactory.getCloseableHttpAsyncClient();
HttpPost httpPost = new HttpPost(url);
if (body != null) {
StringEntity stringEntity = new StringEntity(body, contentType);
httpPost.setEntity(stringEntity);
}
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
// 设置短连接
// httpPost.setHeader(HttpHeaders.CONNECTION, "close");
}
HttpResponseBO responseBO = new HttpResponseBO();
try {
Future<HttpResponse> future = httpClient.execute(httpPost, callback);
HttpResponse response = future.get();
StringWriter stringWriter = new StringWriter();
if (response.getEntity() != null) {
IOUtils.copy(response.getEntity().getContent(), stringWriter, "UTF8");
}
responseBO.setCode(response.getStatusLine().getStatusCode());
responseBO.setContent(stringWriter.toString());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
return responseBO;
}
}
/**
* post 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param charset 编码
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO post(String url, String body, Map<String, String> header, String charset) throws Exception {
return post(url, body, header, charset, null);
}
/**
* post 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param charset 编码
* @param callback 回调方法
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO post(String url, String body, Map<String, String> header, String charset, FutureCallback callback) throws Exception {
CloseableHttpAsyncClient httpClient = AsynHttpClientFactory.getCloseableHttpAsyncClient();
HttpPost httpPost = new HttpPost(url);
if (body != null) {
StringEntity stringEntity = new StringEntity(body, charset);
httpPost.setEntity(stringEntity);
}
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
}
}
HttpResponseBO responseBO = new HttpResponseBO();
try {
Future<HttpResponse> future = httpClient.execute(httpPost, callback);
HttpResponse response = future.get();
StringWriter stringWriter = new StringWriter();
if (response.getEntity() != null) {
IOUtils.copy(response.getEntity().getContent(), stringWriter, "UTF8");
}
responseBO.setCode(response.getStatusLine().getStatusCode());
responseBO.setContent(stringWriter.toString());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
return responseBO;
}
}
/**
* put 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param contentType 编码
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO put(String url, String body, Map<String, String> header, ContentType contentType) throws Exception {
return put(url, body, header, contentType, null);
}
/**
* put 请求
*
* @param url 地址
* @param body body参数
* @param header 请求头
* @param contentType 编码
* @param callback 回调方法
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO put(String url, String body, Map<String, String> header, ContentType contentType, FutureCallback callback) throws Exception {
CloseableHttpAsyncClient httpClient = AsynHttpClientFactory.getCloseableHttpAsyncClient();
HttpPut httpPut = new HttpPut(url);
if (body != null) {
StringEntity stringEntity = new StringEntity(body, contentType);
httpPut.setEntity(stringEntity);
}
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPut.addHeader(entry.getKey(), entry.getValue());
}
}
HttpResponseBO responseBO = new HttpResponseBO();
try {
Future<HttpResponse> future = httpClient.execute(httpPut, callback);
HttpResponse response = future.get();
StringWriter stringWriter = new StringWriter();
if (response.getEntity() != null) {
IOUtils.copy(response.getEntity().getContent(), stringWriter, "UTF8");
}
responseBO.setCode(response.getStatusLine().getStatusCode());
responseBO.setContent(stringWriter.toString());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
httpPut.releaseConnection();
return responseBO;
}
}
/**
* delete 请求
*
* @param url 地址
* @param header 请求头
* @param charset 编码
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO delete(String url, Map<String, String> header, String charset) throws Exception {
return delete(url, header, charset, null);
}
/**
* delete 请求
*
* @param url 地址
* @param header 请求头
* @param charset 编码
* @param callback 回调方法
* @return 请求结果
* @throws Exception 异常信息
*/
public static HttpResponseBO delete(String url, Map<String, String> header, String charset, FutureCallback callback) throws Exception {
if (StringUtils.isBlank(charset)) {
charset = "UTF8";
}
CloseableHttpAsyncClient httpClient = AsynHttpClientFactory.getCloseableHttpAsyncClient();
HttpDelete httpDelete = new HttpDelete(url);
if (MapUtils.isNotEmpty(header)) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpDelete.addHeader(entry.getKey(), entry.getValue());
}
}
HttpResponseBO responseBO = new HttpResponseBO();
try {
Future<HttpResponse> future = httpClient.execute(httpDelete, callback);
HttpResponse response = future.get();
StringWriter stringWriter = new StringWriter();
if (response.getEntity() != null) {
IOUtils.copy(response.getEntity().getContent(), stringWriter, charset);
}
responseBO.setCode(response.getStatusLine().getStatusCode());
responseBO.setContent(stringWriter.toString());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
httpDelete.releaseConnection();
return responseBO;
}
}
}
5、存储响应结果对象
import lombok.Data;
@Data
public class HttpResponseBO {
/**
* 响应码
*/
private int code;
/**
* 响应内容
*/
private String content;
}
6、使用过程中碰到的问题
java.util.concurrent.ExecutionException: java.io.IOException: Connection reset by peer at org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:71) at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:84) at org.apache.http.impl.nio.client.FutureWrapper.get(FutureWrapper.java:70) at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:267) at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:232) at at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
出现问题原因:
1、查看服务器连接信息
参考:https://blog.csdn.net/hightrees/article/details/78608811
原因 TIME_WAIT 过多,默认60s,导致连接失败,修改响应参数
在使用过程中基本出现了连接错误的大部分信息,基本都和服务器连接数有关系,
Connection reset by peer
java.util.concurrent.ExecutionException: java.net.SocketTimeoutException: 10,000 milliseconds timeout on connection http-outgoing-11 [ACTIVE]
java.util.concurrent.ExecutionException: org.apache.http.ConnectionClosedException: Connection closed
一开始排查一直以为是程序代码的问题,因为一开始使用的是HttpClient 同步操作的出现了异常 java.net.SocketException: Broken pipe 以为是每次调用完后没有关闭导致的,就在finally加了如下代码
if (null != httpClient) {
httpClient.close();
}
发现过段时间有开始报错了,就换成了使用 HttpAsynClient 进行nio操作,换完后出现的 java.util.concurrent.ExecutionException: java.net.SocketTimeoutException: 10,000 milliseconds timeout on connection http-outgoing-11 [ACTIVE] 这个错误,因为一开始设置的是5s,改大后发现允许一段时间还是报这个错,就将
/**
* 使用连接池来管理连接,从连接池获取连接的超时时间,0不超时
*/
private static int connectionRequestTimeout = 200000;
给程序调用的get、post、put、delete 的时候每次释放连接 ,添加如下代码
httpPost.releaseConnection();
这个参数给设置成200s发现还是报错,这次异常错误又变了 Connection closed 又郁闷,然后就给初始化后方法
public class AsynHttpClientFactory {
private static CloseableHttpAsyncClient httpclient;
private PoolingNHttpClientConnectionManager connManager;
public AsynHttpClientFactory() {
connManager = HttpAsynClient.getConnManager();
httpclient = HttpAsynClient.getClient(connManager);
httpclient.start();
log.info("异步httpClient启动完成...");
}
public static CloseableHttpAsyncClient getCloseableHttpAsyncClient() {
return httpclient;
}
}
改成
public class AsynHttpClientFactory {
private static CloseableHttpAsyncClient httpclient;
private PoolingNHttpClientConnectionManager connManager;
public AsynHttpClientFactory() {
connManager = HttpAsynClient.getConnManager();
httpclient = HttpAsynClient.getClient(connManager);
httpclient.start();
log.info("异步httpClient启动完成...");
}
public static CloseableHttpAsyncClient getCloseableHttpAsyncClient() {
if (!httpclient.isRunning()) {
new AsynHttpClientFactory();
}
return httpclient;
}
}
判断如果关闭了就重新创建,这下好了,不报这个错了,又开始报
Connection reset by peer
改来改去不知道怎么改了,郁闷,发现能改的地方基本都改了,发现还是不行,一直想的是,本地和测试都没出现该问题,只有正式环境最近频繁出现,忽然想到是不是和连接数太多导致的一直创建不了,因为根据我创建的连接池数最多100,不应该出现该问题,所以一直没往服务器那边想,最后查询发现是服务器连接等待释放的资源太多,测试环境基本没有,所以测试环境没出现问题,因为正是环境还有好多其他请求,查询了下服务器连接信息,发现time_wait等待释放的有5000,看网上的5000都在正常范围之内,为什么这么点就不行,没办法就开始改这个参数,默认是60s才释放,后面改成1s释放,数值降到2000左右,才没有出现问题。
java.util.concurrent.ExecutionException: org.apache.http.ConnectionClosedException: Connection closed
at org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:71)
at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:84)
at org.apache.http.impl.nio.client.FutureWrapper.get(FutureWrapper.java:70)
at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:267)
at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:232)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
java.util.concurrent.ExecutionException: java.net.SocketTimeoutException: 10,000 milliseconds timeout on connection http-outgoing-11 [ACTIVE]
at org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:71)
at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:84)
at org.apache.http.impl.nio.client.FutureWrapper.get(FutureWrapper.java:70)
at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:273)
at com.util.nio.HttpAsynClientUtils.put(HttpAsynClientUtils.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Caused by: java.net.SocketTimeoutException: 10,000 milliseconds timeout on connection http-outgoing-11 [ACTIVE]
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:381)
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:92)
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:175)
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:263)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:492)
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:213)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)
at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:876)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:847)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:160)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:120)
at org.apache.http.entity.StringEntity.writeTo(StringEntity.java:167)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:160)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.util.HttpClientUtils.put(HttpClientUtils.java:192)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)