【发布时间】:2019-01-01 20:51:23
【问题描述】:
我正在使用 akka actor 来实现一些 http 请求的并行处理。我已经使用RoundRobinPool 初始化了一组演员,例如:
ActorRef myActorPool = actorSystem.actorOf(new RoundRobinPool(200).props(Props.create(MyActor.class, args)), MyActor.class.getSimpleName());
它工作正常。但是在进程运行一段时间后,我收到以下错误
java.util.concurrent.CompletionException: akka.pattern.AskTimeoutException: Recipient[Actor[akka://web_server/user/MyActor#-769383443]] 已经被终止。 Sender[null] 发送了“com.data.model.Request”类型的消息。
所以我重写了postStop 方法,在那里添加了一条日志语句。
@Override
public void postStop() {
log.warn("Actor is stopped");
}
现在,我可以在日志中看到演员正在停止。但我不确定它是针对哪个请求发生的。一旦池中的所有参与者都终止(200 是我设置的池大小),我会得到AskTimeoutException,如前所述。无论如何要调试演员被终止的原因吗?
编辑 1
在控制器中,我使用创建的演员池,如
CompletableFuture<Object> s = ask(myActorPool, request, 1000000000).toCompletableFuture();
return s.join();
actor 只处理一种消息。
@Override
public AbstractActor.Receive createReceive() {
return receiveBuilder()
.match(Request.class, this::process)
.build();
}
private void process(Request request) {
try {
// code here
} catch (Exception e) {
log.error(e.getMessage(), e);
getSender().tell(new akka.actor.Status.Failure(e), getSelf());
}
}
【问题讨论】:
-
如果您可以添加有用的代码片段。
-
这就是你创建演员的方式。您实际上是如何使用演员的?
-
查看代码似乎只有在出现异常时(在 catch 块中)才向发送者发送响应。您还需要在
try块中发送响应。 -
我没有在
try块中添加代码,但它实际上向发件人发送了响应。 -
我不知道它是否与此问题有关,但您正在阻止
s.join()上的线程。根据您的项目设置/框架,您可能会用完可用线程,因此整个应用程序可能会运行缓慢,从而导致超时。
标签: java scala akka actor timeoutexception