天天看點

http線程池的優化

我們原來用的httpClient一直都是com.ning.http.client.AsyncHttpClient(線程池管理類),需要的時候申請,不需要的時候釋放。并發比較高的情況下,存在http連結不釋放的問題,更新了版本也解決不了,我最近對它進行了一次重構,徹底解決了這個問題

替換的思路就是用ThreadLocal來為每一個線程配置設定一個HttpClient,使用後自己釋放連結,這樣每個線程就不用重複構造HttpClient。同時為了盡可能減少記憶體的申請,為在函數調用過程中申請的變量都申請了ThreadLocal變量,demo如下

import java.io.ByteArrayOutputStream;

import java.io.InputStream;

import java.net.URLDecoder;

import org.apache.commons.httpclient.HttpStatus;

import org.apache.commons.httpclient.URI;

import org.apache.commons.httpclient.methods.GetMethod;

import org.apache.commons.httpclient.methods.PostMethod;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

@SuppressWarnings("deprecation")

public class HttpClient {

private static final Logger log = LoggerFactory.getLogger(HttpClient.class);

private static ThreadLocal<org.apache.commons.httpclient.HttpClient> threadHttpClient = new ThreadLocal<org.apache.commons.httpclient.HttpClient>();

private static ThreadLocal<PostMethod> threadPostMethod = new ThreadLocal<PostMethod>();

private static ThreadLocal<GetMethod> threadGetMethod = new ThreadLocal<GetMethod>();

private static ThreadLocal<ByteArrayOutputStream> threadByteArrayOutputStream = new ThreadLocal<ByteArrayOutputStream>();

private static ThreadLocal<byte[]> threadByte = new ThreadLocal<byte[]>();

public static String doPost(String url, String requestJson) throws Exception {

org.apache.commons.httpclient.HttpClient client = getHttpClient();

PostMethod method = getPostMethod();

try {

URI base = new URI(url, false);

method.setURI(base);

method.setRequestBody(requestJson);

method.setRequestHeader("Content-Type", "application/json;charset=utf-8");

int result = client.executeMethod(method);

if (result == HttpStatus.SC_OK) {

InputStream in = method.getResponseBodyAsStream();

ByteArrayOutputStream baos = getByteArrayOutputStream();

byte[] buffer = getByte();

int len = 0;

while ((len = in.read(buffer)) != -1) {

baos.write(buffer, 0, len);

}

return URLDecoder.decode(baos.toString(), "UTF-8");

} else {

log.error("HTTP ERROR Status: " + method.getStatusCode() + ":" + method.getStatusText());

return null;

}

} finally {

method.releaseConnection();

}

}

public static String doGet(String url) throws Exception {

org.apache.commons.httpclient.HttpClient client = getHttpClient();

GetMethod method = getGetMethod();

try {

URI base = new URI(url, false);

method.setURI(base);

int result = client.executeMethod(method);

if (result == HttpStatus.SC_OK) {

InputStream in = method.getResponseBodyAsStream();

ByteArrayOutputStream baos = getByteArrayOutputStream();

byte[] buffer = getByte();

int len = 0;

while ((len = in.read(buffer)) != -1) {

baos.write(buffer, 0, len);

}

return URLDecoder.decode(baos.toString(), "UTF-8");

} else {

log.error("HTTP ERROR Status: " + method.getStatusCode() + ":" + method.getStatusText());

return null;

}

} finally {

method.releaseConnection();

}

}

private static org.apache.commons.httpclient.HttpClient getHttpClient() {

org.apache.commons.httpclient.HttpClient client = threadHttpClient.get();

if (client == null) {

client = new org.apache.commons.httpclient.HttpClient();

threadHttpClient.set(client);

log.info("new HttpClient");

}

return client;

}

private static PostMethod getPostMethod() {

PostMethod post = threadPostMethod.get();

if (post == null) {

post = new PostMethod();

threadPostMethod.set(post);

log.info("new PostMethod");

}

post.recycle();

return post;

}

private static GetMethod getGetMethod() {

GetMethod get = threadGetMethod.get();

if (get == null) {

get = new GetMethod();

threadGetMethod.set(get);

log.info("new GetMethod");

}

get.recycle();

return get;

}

private static ByteArrayOutputStream getByteArrayOutputStream() {

ByteArrayOutputStream get = threadByteArrayOutputStream.get();

if (get == null) {

get = new ByteArrayOutputStream();

threadByteArrayOutputStream.set(get);

log.info("new ByteArrayOutputStream");

}

get.reset();

return get;

}

private static byte[] getByte() {

byte[] get = threadByte.get();

if (get == null) {

get = new byte[1024];

threadByte.set(get);

log.info("new byte[]");

}

return get;

}

}

繼續閱讀