gpt4 book ai didi

java - 处理多线程/传出 http 请求

转载 作者:太空宇宙 更新时间:2023-11-04 06:44:39 26 4
gpt4 key购买 nike

我正在开发一个 Java/Spring Web 应用程序,它对每个传入请求执行以下操作:

  1. 向第三方网络服务器发出大量请求,
  2. 检索每个人的响应,
  3. 将每个响应解析为 JSON 对象列表,
  4. 将 JSON 对象列表整理成单个列表并返回它。

我正在为发送到第三方网络服务器的每个请求创建一个单独的线程。我正在使用 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

提前致谢

最佳答案

我不建议将其实现为同步服务。异步进行。获取您的请求,池化可调用对象,并返回一个资源位置,客户端稍后可以在其中请求结果。

您必须将这些可调用对象集中在执行程序中。在后台进程中轮询执行程序,并在您在第一个请求时返回的位置中提供结果。通过这种方式,可以更轻松地控制可用资源,并在没有更多可用资源时彻底拒绝处理请求。

非阻塞IO不会减少线程数量,它只是将“工作”委托(delegate)给另一个线程,以便服务线程不被阻塞并能够接收更多请求。

使用休息。

接收 POST 请求,并回答如下内容:

    HTTP/1.1 202 Accepted
Location: /result/to/consult/later

然后,客户端可以在给定位置请求结果。如果处理尚未完成,则回答:

HTTP/1.1 201 Created

如果完成,则返回 HTTP/1.1 200 OK 以及生成的 JSON。

关于java - 处理多线程/传出 http 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24166747/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com