我正在 Play Framework 中构建一个应用程序,该应用程序必须进行一些密集的文件解析。该解析涉及解析多个文件,最好是并行解析。
用户上传一个存档,该存档被解压缩并且文件存储在驱动器上。
在该存档中,有一个包含多个列的文件(我们称之为 main.csv
)。其中一个列是存档中另一个文件的名称(例如 subPage1.csv
)。此列可以为空,因此 main.csv
中并非所有行都有子页面。
现在,我启动一个 Akka Actor 来解析 main.csv 文件。在这个 Actor 中,使用 @Inject
,我有另一个 ActorRef
public MainParser extends ActorRef {
@Inject
@Named("subPageParser")
private AcgtorRef subPageParser;
public Receive createReceive() {
...
if (column[3] != null) {
subPageParser.tell(column[3], getSelf());
}
}
}
子页面解析器 Prop :
public static Props getProps(JPAApi jpaApi) {
return new RoundRobinPool(3).props(Props.create((Class<?>) SubPageParser.class, jpaApi));
}
现在,我的问题是这样的。考虑到子页面可能需要 5 秒才能解析,我将使用 SubPageParser
的单个实例,还是有多个实例并行执行处理。
此外,考虑另一种情况,其中名称存储在数据库中,我使用类似这样的内容:
List<String> names = dao.getNames();
for (String name: names) {
subPageParser.tell(name, null);
}
这样的话,考虑到subPageParser
ActorRef是像之前一样使用Guice @Inject获得的,我会进行并行处理吗?
如果我并行处理,如何控制生成的 Actor 数量?如果我有 1000 个子页面,我不需要 1000 个 Actor。此外,它们的生命周期可能是一个问题。
注意: 我有一个像这样的 ActorsModule,这样我就可以使用 @Inject 而不是 Props:
public class ActorsModule extends AbstractModule implements AkkaGuiceSupport {
@Override
protected void configure() {
bindActor(MainParser.class, "mainparser");
Function<Props, Props> props = p -> SubPageParser.getProps();
bindActor(SubPageParser.class, "subPageParser", props);
}
}
更新:我已修改为使用 RoundRobinPool。然而,这并没有按预期工作。我指定 3 作为实例数,但我在 if 中为每个解析请求获得一个新对象。
最佳答案
像您一样注入(inject)一个 actor 将导致每个 MainParser
都有一个 SubPageParser
。虽然您可能会向它发送 1000 条消息(使用 tell
),但它们会被一一处理,而其他消息则在邮箱中等待处理。
关于您的设计,您需要注意,注入(inject)这样的 Actor 将创建另一个顶级 Actor,而不是创建 SubPageParser
作为子 Actor,这将允许父 Actor来控制和监视它。 playframework 支持注入(inject) child Actor ,如其文档中所述:https://www.playframework.com/documentation/2.6.x/JavaAkka#Dependency-injecting-child-actors
虽然你可以让 akka 使用一定数量的子 actor 来分配负载,但我认为你应该质疑为什么你首先使用 actor。大多数问题都可以通过简单的 Future
来解决。例如,您可以配置自定义线程池来运行您的 Future
,并让它们按照您的意愿在并行级别上完成工作:https://www.playframework.com/documentation/2.6.x/ThreadPools#Using-other-thread-pools
关于java - 使用@Inject时的Actor数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47249002/