Http Client接続池小記
**公衆番号に注目してください。**
*WeChatをスキャンします
Springboot統合http接続池をおすすめします。https://blog.csdn.net/hellozpc/article/details/106861972でよく使われるhttpクライアントは、JDK元のURLConnection、Nettyの非同期HTTP Cient、SpringのRestTemplate、Spring CoudのFeignがあります。RertTemplate、Feignは非常に便利ですが、下の詳細を多すぎて、全体をコントロールするのには不利です。 ここでは主にApphe HttpClientによるhttp接続池の処理を記載します。ネット上の多くの文章は定期的にチェックしていません。無効な接続機能をオフにします。また、jvmフックを登録して、プログラム終了時にhttp Clientのインスタンスを閉じます。
*WeChatをスキャンします
*WeChatをスキャンします
Springboot統合http接続池をおすすめします。https://blog.csdn.net/hellozpc/article/details/106861972
/**
* HttpTemplate#execute http post
* @author zhoupengcheng
*/
public class HttpTemplate {
private static Logger logger = LoggerFactory.getLogger(HttpTemplate.class);
private static final String DEFAULT_ACCEPTTYPE = "application/json;charset=utf-8";
private static final String DEFAULT_CHARSET = "utf-8";
/**
*
*/
private static final int MAX_CONNECTION_NUM = 20;
/**
*
*/
private static final int MAX_PER_ROUTE = 20;
/**
* , 3
*/
private static final int DEFAULT_CONNECTION_TIMEOUT = 3000;
/**
* , 3
*/
private static final int DEFAULT_READ_TIMEOUT = 3000;
/**
*
*/
private PoolingHttpClientConnectionManager cm;
private CloseableHttpClient httpClient;
/**
*
*/
private ObjectMapper objectMapper;
public HttpTemplate() {
init();
}
public void init() {
initObjectMapper();
initHttpClient();
}
private void initHttpClient() {
HttpClientBuilder builder = HttpClients.custom();
builder.disableCookieManagement();
builder.disableRedirectHandling();
builder.disableAutomaticRetries();
builder.setConnectionManagerShared(false)
.evictIdleConnections(1, TimeUnit.MINUTES)//
.evictExpiredConnections()//
.setConnectionTimeToLive(1, TimeUnit.MINUTES) // , ,
.setDefaultRequestConfig(
RequestConfig
.custom()
.setAuthenticationEnabled(false)
.setCircularRedirectsAllowed(false)
.setSocketTimeout(DEFAULT_READ_TIMEOUT)
.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT)
.setConnectionRequestTimeout(1000)
.setCookieSpec(CookieSpecs.IGNORE_COOKIES)
.build()) //
.setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE) // keepAlive
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)// ,
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))// 3
.build();
Registry socketFactoryRegistry =
RegistryBuilder.create()
.register("https", PlainConnectionSocketFactory.getSocketFactory())
.register("http", new PlainConnectionSocketFactory()).build();
final int conExpire = 15;// ,
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, conExpire,
TimeUnit.SECONDS);
cm.setDefaultConnectionConfig(ConnectionConfig.DEFAULT);
cm.setMaxTotal(MAX_CONNECTION_NUM);
cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
// , , nagle
cm.setDefaultSocketConfig(SocketConfig.custom().setSoKeepAlive(true).setSoTimeout(DEFAULT_READ_TIMEOUT).setTcpNoDelay(true).build());
cm.setValidateAfterInactivity(-1);// ,
builder.setConnectionManager(cm);
builder.setConnectionManagerShared(false);
httpClient = builder.build();
//
Thread staleCheckThread = new Thread(() -> {
while (true) {
try {
Thread.sleep(10000);
cm.closeExpiredConnections();
cm.closeIdleConnections(conExpire, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("stale check exception", e);
}
}
}, "HttpInvoker-coonection-stale-check-thread");
//
staleCheckThread.setDaemon(true);
staleCheckThread.start();
// , httpClient
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
httpClient.close();
logger.info(">>>>httpClient closed<<<
* @return
* @throws Exception
*/
public R execute(String path, Object req, TypeReference typeReference) throws Exception {
if (typeReference == null) {
typeReference = (TypeReference) new TypeReference() {
};
}
String reqBody = objectMapper.writeValueAsString(req);
logger.info("reqBody:{}", reqBody);
HttpPost httpPost = new HttpPost(path);
httpPost.setProtocolVersion(HttpVersion.HTTP_1_1);
httpPost.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE);
httpPost.setConfig(RequestConfig.custom().setSocketTimeout(DEFAULT_READ_TIMEOUT)
.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT).build());
httpPost.addHeader("Accept", DEFAULT_ACCEPTTYPE);
httpPost.addHeader("Content-Type", DEFAULT_ACCEPTTYPE);
HttpEntity httpEntity = new StringEntity(reqBody, DEFAULT_CHARSET);
httpPost.setEntity(httpEntity);
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
String responseBody = EntityUtils.toString(httpResponse.getEntity(), DEFAULT_CHARSET);
logger.info("resBody:{}", responseBody);
return objectMapper.readValue(responseBody, typeReference);
}
/**
* demo
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
HttpTemplate httpTemplate = new HttpTemplate();
Order order = new Order();
order.id = "1111111";
order.cancleRemarks = " ";
order.createDate = LocalDateTime.now();
order.startLongitude = "1356.4343";
OrderResponse orderResponse = httpTemplate.execute("http://127.0.0.1:8888/ordersdispatch", order, new TypeReference() {
});
// OrderResponse Response
Response response = httpTemplate.execute("http://127.0.0.1:8888/orderdispatch", order, null);
logger.info("orderResponse:{}", orderResponse);
logger.info("response:{}", response);
}
}
public class Order {
public String id;
public String orderCode;
public String startCityName;
public String startAddress;
public String startAddDtl;
public String startLongitude;
public String startLatitude;
public String endCityName;
public String endAddress;
public String endAddDtl;
public String endLongitude;
public String endLatitude;
public byte prodType;
public LocalDateTime orderDate;
public int orderDay;
public String flightNo;
public String remark;
public int orderState;
public String driverId;
public String driverUid;
public String driverMobile;
public String source;
public LocalDateTime createDate;
public LocalDateTime updateDate;
public String dispatchType;
public String driverRemark;
public LocalDateTime flightDate;
public String flightArrCode;
public String flightDepCode;
public String cancleRemarks;
public LocalDateTime endTime;
}
/**
* http
*/
public class Response {
public static int SUCCESS_CODE = 0;
public Integer retCode;
public String retMsg;
public static boolean isSuccess(Response res) {
return res != null && res.retCode == SUCCESS_CODE;
}
@Override
public String toString() {
return "Response{" +
"retCode=" + retCode +
", retMsg='" + retMsg + '\'' +
'}';
}
}
public class OrderResponse extends Response {
public List info;
}
**公衆番号に注目してください。***WeChatをスキャンします