使用Akka演员下载许多文件

时间:2017-05-15 06:35:16

标签: java http tcp akka

背景

我正在尝试使用Akka actor下载许多文件。 (Akka 2.5.1& Java 8)

每位演员都会分配一个应该从中下载的不同网址。

另一个演员正在创建下载者演员,不应该等待下载者完成。一旦完成,他们将创建另一个actor来处理下载的文件。

问题

当我只运行一个演员时 - 它可以下载该文件。

随着我增加演员的数量,似乎没有人能够完成任务。他们正在下载部分文件并停止,没有特别的错误/异常。

演员创作代码:

ActorRef downloaderActor = context().actorOf(Props.create(DownloaderActor.class)); downloaderActor.tell("URL to download", this.getSelf());

在DownloaderActor类中,我有一个下载功能,似乎问题出现了:

public void downloadFile(String fileURL, String saveDir) {
        try {
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = httpConn.getInputStream();
                String saveFilePath = saveDir + File.separator + fileName;
                FileOutputStream outputStream = new FileOutputStream(saveFilePath);

                int bytesRead = -1;
                byte[] buffer = new byte[4096];
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.close();
                inputStream.close();
                System.out.println("File downloaded: " + fileURL);
            } else {
                System.out.println("No file to download. Server replied HTTP code: " + responseCode + " . when accessing " + url);
            }
            httpConn.disconnect();
        }catch (MalformedURLException murl){
            murl.printStackTrace();
        }catch (IOException ioe){
            ioe.printStackTrace();
        }
}

更具体一点 - 问题似乎是在“while”循环中,因为如果我添加了日志记录,我可以看到循环是循环而不是在一段时间后停止。

尝试失败

我还试图设置一些http连接参数:

httpConn.setRequestProperty("Range", "bytes=0-24"); httpConn.setConnectTimeout(10_000_000);

但它似乎没有帮助。

我尝试将下载功能作为静态功能放在不同的Util类中,但也没有帮助。

这里会提供任何帮助。

2 个答案:

答案 0 :(得分:0)

您在此处使用阻止I / O来下载文件,这意味着每个并发下载都需要一个线程。

你是正确的轨道,因为Actor模型可以帮助你建模你的问题而不需要每个并发下载一个线程:actor是建模并发异步过程的好方法。

然而,要真正利用这一点,您仍然需要编写“实施”'演员是非阻挡的。 Scala可以使用许多非阻塞的HTTP库,例如,您可以将akka-http's future-based client API与“问题”一起使用。图案。

答案 1 :(得分:0)

我发现问题的根源:

我在Junit上下文中运行代码。似乎Junit在某些时候切断了正在运行的线程,从而终止了演员的活动。

一旦我开始以常规运行模式运行程序,问题(似乎)就消失了。