处理多个线程/传出的http请求

时间:2014-06-11 15:22:46

标签: java multithreading spring network-programming

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

  1. 向第三方Web服务器发出大量请求,
  2. 从每个
  3. 检索响应
  4. 将每个响应解析为JSON对象列表,
  5. 将JSON对象列表整理到一个列表中并返回它。
  6. 我正在为发送到第三方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

    提前致谢

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