-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHttpClientConfig.txt
147 lines (132 loc) · 6.45 KB
/
HttpClientConfig.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
public class HttpClientConfig {
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", buildSSLConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(reg);
//将最大连接数增加到 800
connectionManager.setMaxTotal(800);
// 将每个路由基础的连接增加到 50
connectionManager.setDefaultMaxPerRoute(50);//例如默认每路由最高50并发,具体依据业务来定
return connectionManager;
}
@Bean(value = "httpClient")
@Primary
public HttpClient httpClient(PoolingHttpClientConnectionManager connectionManager) {
// 配置请求的超时设置
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //连接目标URL超时时间
.setConnectionRequestTimeout(800) //从连接池获取连接超时时间
.setSocketTimeout(50000) //当30秒钟还没有响应刚抛出异常(临时增大等待时间, 等待轻卡返回)
.build();
HttpClient httpClient = HttpClients.custom()
//关闭cookie
.disableCookieManagement()
//解决post/redirect/post 302跳转问题
.setRedirectStrategy(new CustomRedirectStrategy())
.setConnectionManager(connectionManager)
.setKeepAliveStrategy(connectionKeepAliveStrategy())
.setDefaultRequestConfig(requestConfig)
.build();
log.info("初始化httpClient连接池完成...");
new IdleConnectionMonitorThread(connectionManager, httpClient).start();
log.info("启动连接监控器,自动关闭闲置、过期");
return httpClient;
}
private SSLConnectionSocketFactory buildSSLConnectionSocketFactory() {
try {
SSLContext sslContext = createIgnoreVerifySSL();
String[] supportedProtocols = new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"};
log.debug("supportedProtocols: {}", String.join(", ", supportedProtocols));
//优先绕过安全证书 NoopHostnameVerifier 永远不会抛出 SSLException,这里使用默认的 DefaultHostnameVerifier
return new SSLConnectionSocketFactory(sslContext, supportedProtocols, null,
new DefaultHostnameVerifier());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
log.error("ssl connection fail", e);
}
return SSLConnectionSocketFactory.getSocketFactory();
}
public SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
private ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
ConnectionKeepAliveStrategy myStrategy = (response, 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 60 * 1000;//如果没有约定,则默认定义时长为60s
};
return myStrategy;
}
private static class IdleConnectionMonitorThread extends Thread {
private final PoolingHttpClientConnectionManager connMgr;
private final HttpClient httpClient;
private volatile boolean shutdown;
public IdleConnectionMonitorThread(PoolingHttpClientConnectionManager connMgr, HttpClient httpClient) {
super();
this.connMgr = connMgr;
this.httpClient = httpClient;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(60000);
// Close expired connections
connMgr.closeExpiredConnections();
// Optionally, close connections
// that have been idle longer than 30 sec
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
// Set<HttpRoute> routes = connMgr.getRoutes();
// if (!CollectionUtils.isEmpty(routes)) {
// String httpRoute = routes.stream().map(HttpRoute::toString).collect(Collectors.joining(","));
// log.info("HttpRoute: {}", httpRoute);
// }
// Look at pool stats.
log.info("Pool Stats: {}", connMgr.getTotalStats());
if (httpClient != null) {
Configurable client = (Configurable) httpClient;
RequestConfig config = client.getConfig();
log.info("http client : {}", config.toString());
}
}
}
} catch (InterruptedException ex) {
// terminate
log.warn("fail to close idle connections.{}", ex.getMessage());
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
}