我使用的是akka 2.2.3版。 我有一个使用Akka camel消费模式的消息传递应用程序。我在日志中看到以下错误:
java.util.concurrent.TimeoutException: Failed to get response from the actor [ActorEndpointPath(akka://producer-subscriber/user/subscriber)] within timeout [3 seconds]. Check replyTimeout and blocking settings [Endpoint[akka://producer-subscriber/user/subscriber?autoAck=true&replyTimeout=3+seconds]]
at akka.camel.internal.component.ActorProducer$$anonfun$1.applyOrElse(ActorComponent.scala:158)
at akka.camel.internal.component.ActorProducer$$anonfun$1.applyOrElse(ActorComponent.scala:155)
at scala.runtime.AbstractPartialFunction$mcVL$sp.apply$mcVL$sp(AbstractPartialFunction.scala:33)
at scala.runtime.AbstractPartialFunction$mcVL$sp.apply(AbstractPartialFunction.scala:33)
at scala.runtime.AbstractPartialFunction$mcVL$sp.apply(AbstractPartialFunction.scala:25)
at scala.PartialFunction$AndThen.apply(PartialFunction.scala:181)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:67)
at akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:82)
at akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
at akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
at akka.dispatch.BatchingExecutor$Batch.run(BatchingExecutor.scala:58)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
消费者的创建发生在另一个类中,如下所示,我将对父类的引用传递给消费者:
val subscriber = system.actorOf(Props(new Subscriber(solaceAssistant, self)), name = "subscriber")
这里是消费者类本身
import akka.actor.{ReceiveTimeout, ActorLogging, ActorRef, Props}
import akka.camel.{CamelMessage, Consumer}
import org.apache.camel.RuntimeCamelException
import scala.concurrent.duration._
import scala.language.postfixOps
import scala.util.{Failure, Success, Try}
class Subscriber(settings: SolaceAssistant, parent: ActorRef) extends Consumer with ActorLogging {
override val endpointUri = settings.solaceDefaults.TOPIC_ENDPOINT
val topic = settings.solaceDefaults.TOPIC
val marshallingService = settings.marshallingService
override def autoAck = true
override def replyTimeout = 3 seconds
def receive = {
case camelMsg: CamelMessage =>
parent ! MessageReceived(unmarshalMessage(camelMsg))
case r: ReceiveTimeout ⇒ parent ! MessageReceived(false)
case err: RuntimeCamelException =>
parent ! MessageReceived(false)
case e: java.util.concurrent.TimeoutException =>
log.info("Time out breached")
parent ! MessageReceived(false)
case other: Any =>
log.info("Other msg received")
parent ! MessageReceived(false)
}
}
原始父类是否还必须将receiveTimeout实现为其receive方法的一部分?我不知道如何防止错误发生。我可以根据需要提供更多细节。