将多个POST请求同时发送到一个URL

时间:2016-02-03 15:40:13

标签: java multithreading http post concurrency

主要目标是通过REST服务将xml文件从一个文件夹发送到Cassandra DB。我想要做的只是读取某个文件夹中的所有文件,并创建一个文件路径设置到其中的Worker对象。

while (RUNS > 0) {
            ExecutorService executor = Executors.newFixedThreadPool(N_THREADS);

            File dir = new File(PATH_TO_SAMPLES);
            File[] listFiles = dir.listFiles();

            if (listFiles != null) {

                for (File file : listFiles) {

                    Worker worker = new Worker();
                    worker.setPath(file.toPath());

                    executor.submit(worker);
                }
            }

            executor.shutdown();

            // Wait until all threads are finish
            while (!executor.isTerminated()) {
            }

            Thread.sleep(1000);

            RUNS--;
        }

在该执行程序获取工作器实例并转到目录中的下一个文件之后。 RUNS使用迭代总数值初始化,默认值为100_000。 N_THREADS - 线程总数,默认设置为100。

Worker类实现Runnable。运行方法:

@Override
    public void run() {

        String url = getUrl();
        String payload = "xml_file_representation";

        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

        HttpClient client = new HttpClient();

        HttpConnectionManagerParams httpConnectionManagerParams = new HttpConnectionManagerParams();
        connectionManager.setParams(httpConnectionManagerParams);

        client.setHttpConnectionManager(connectionManager);

        PostMethod postMethod = new PostMethod(url);

        try {

            postMethod.setRequestHeader("User-Agent", USER_AGENT);
            postMethod.setRequestHeader("Content-Type", "application/xml");

            postMethod.setRequestEntity(new StringRequestEntity(payload, "application/xml", StandardCharsets.UTF_8.toString()));

            int statusCode = client.executeMethod(postMethod);

            InputStream body = postMethod.getResponseBodyAsStream();

            if (statusCode == HttpStatus.SC_OK) {

                //OK
            }

        } catch (Exception e) {
            LOG.error("POST: ERROR!");
        } finally {
            postMethod.releaseConnection();
            connectionManager.shutdown();
        }
    }

如果我删除等待,即

  

了Thread.sleep(1000);

在运行结束时,当 ~16_000 请求被发送时,我将获得例外:

java.net.BindException: Address already in use

这与BindException: address already in use on a client socket?

非常相似

无论如何,接受的答案对我没有帮助。我没有更多的想法,我需要做什么来关闭这些“连接”,以防止该错误。

Thread.sleep()这样的解决方法也不像是一个好的解决方案。感谢您提供任何帮助或建议。

1 个答案:

答案 0 :(得分:0)

为每个工人创建一个conn mgr会破坏conn mgr的目的。它应该在线程之间共享,从Berger链接的其他帖子来判断。 它就像没有。

操作系统保持套接字在关闭后保持不变。除了将套接字(连接)与其他问题中提出的设计重复使用之外,您无能为力。

除非你想冒险使用Socket.setSOLinger()TCP option SO_LINGER (zero) - when it's required

Thread.sleep(1000)当然不是一个可行的选择,因为你可能需要另外一天超过1秒......或者操作系统可以在其他情况下改变那些挥之不去的套接字。