背景
我正在尝试使用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类中,但也没有帮助。
这里会提供任何帮助。
答案 0 :(得分:0)
您在此处使用阻止I / O来下载文件,这意味着每个并发下载都需要一个线程。
你是正确的轨道,因为Actor模型可以帮助你建模你的问题而不需要每个并发下载一个线程:actor是建模并发异步过程的好方法。
然而,要真正利用这一点,您仍然需要编写“实施”'演员是非阻挡的。 Scala可以使用许多非阻塞的HTTP库,例如,您可以将akka-http's future-based client API与“问题”一起使用。图案。
答案 1 :(得分:0)
我发现问题的根源:
我在Junit上下文中运行代码。似乎Junit在某些时候切断了正在运行的线程,从而终止了演员的活动。
一旦我开始以常规运行模式运行程序,问题(似乎)就消失了。