我正在开发一个Java / Spring Web应用程序,每个传入的请求都会执行以下操作:
我正在为发送到第三方Web服务器的每个请求创建一个单独的线程。我正在使用Apache PoolingClientConnectionManager。以下是我正在使用的代码的大纲:
public class Background {
static class CallableThread implements Callable<ArrayList<JSONObject>> {
private HttpClient httpClient;
private HttpGet httpGet;
public CallableThread(HttpClient httpClient, HttpGet httpGet) {
this.httpClient = httpClient;
this.httpGet = httpGet;
}
@Override
public ArrayList<JSONObject> call() throws Exception {
HttpResponse response = httpClient.execute(httpGet);
return parseResponse(response);
}
private ArrayList<JSONObject> parseResponse(HttpResponse response) {
ArrayList<JSONObject> list = null;
// details omitted
return list;
}
}
public ArrayList<JSONObject> getData(List<String> urlList, PoolingClientConnectionManager connManager) {
ArrayList<JSONObject> jsonObjectsList = null;
int numThreads = urlList.size();
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
List<Future<ArrayList<JSONObject>>> list = new ArrayList<Future<ArrayList<JSONObject>>>();
HttpClient httpClient = new DefaultHttpClient(connManager);
for (String url : urlList) {
HttpGet httpGet = new HttpGet(url);
CallableThread worker = new CallableThread(httpClient, httpGet);
Future<ArrayList<JSONObject>> submit = executor.submit(worker);
list.add(submit);
}
for (Future<ArrayList<JSONObject>> future : list) {
try {
if (future != null) {
if (jsonObjectsList == null) {
jsonObjectsList = future.get();
} else {
if (future.get() != null) {
jsonObjectsList.addAll(future.get());
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
return jsonObjectsList;
}
}
一切正常。我的问题是,随着网站流量的增加,此代码的扩展程度如何?有没有更好的方法来实现这个?例如,通过实现非阻塞I / O来减少正在创建的线程数。是否有可能有用的库或框架?
目前,我正在使用Java 6和Spring Framework 3.1
提前致谢
答案 0 :(得分:1)
我不建议将其作为同步服务来实现。异步进行。获取您的请求,汇集可调用对象,并返回客户端稍后可以请求结果的资源位置。
你必须在执行者中汇集这些callables。在后台进程中轮询执行程序,并在第一次请求时返回的位置中提供结果。这样做,控制可用的资源会更容易,如果没有更多可用的资源,则干净地拒绝处理请求。
非阻塞IO不会减少线程数,它只是将“作业”委托给另一个线程,以便不阻止服务线程并能够接收更多请求。
使用REST。
接收POST请求,并回答如下:
HTTP/1.1 202 Accepted
Location: /result/to/consult/later
然后,客户端可以在给定位置请求resutl。如果处理尚未完成,请回答:
HTTP/1.1 201 Created
如果已完成,则返回带有结果JSON的HTTP/1.1 200 OK
。