使用Akka Actors

时间:2015-08-13 18:38:56

标签: scala rabbitmq akka actor

我有一个应用程序使用来自RabbitMQ的消息,并且我使用Actors来处理工作。

这是我的方法:

object QueueConsumer extends Queue {

  def consumeMessages = {
    setupListener(buildChannel(resultsQueueName), resultsQueueName,
        resultsCallback)
  }

  private def setupListener(receivingChannel: Channel, queue: String, 
        f: (String) => Any) {
    Akka.system.scheduler.scheduleOnce(Duration(10, TimeUnit.SECONDS),
      Akka.system.actorOf(Props(new QueueActor(receivingChannel, queue, f))), "")
  }

}

class QueueActor(channel:Channel, queue:String, f:(String) => Any) extends Actor{

  def receive = {
    case _ => startReceiving
  }

  def startReceiving = {
    val consumer = new QueueingConsumer(channel)
    channel.basicConsume(queue, false, consumer)
    while (true) {
      val delivery = consumer.nextDelivery()
      val msg = new String(delivery.getBody())
      context.actorOf(Props(new Actor {
    def receive = {
      case some: String => f(some)
    }
      })) ! msg
      channel.basicAck(delivery.getEnvelope.getDeliveryTag, false)
    }
  }

}

运行几秒钟后,它会抛出 java.lang.OutOfMemoryError:超出GC开销限制

我认为它正在发生,因为我为我收到的每条消息开始一个新的演员 - 所以如果我有100000条消息,它将创建10万个演员。这是一个好方法,还是应该实现类似“演员池”的内容?

任何人都知道如何在我的场景中避免OutOfMemoryError?

提前感谢。

EDIT1:

改变方法:

class Queue2(json:String) extends Actor {

  def receive = {
    case x: String =>
      val envelope = MessageEnvelopeParser.toObject(x)
      val processor = ProcessQueueServiceFactory.getProcessResultsService()
      envelope.messages.foreach(message => processor.process(message))
  }

}

object Queue2 {
  def props(json: String): Props = Props(new Queue2(json))
}

class QueueActor(channel:Channel, queue:String) extends Actor {

  def receive = {
    case _ => startReceiving
  }

  def startReceiving = {
    val consumer = new QueueingConsumer(channel)
    channel.basicConsume(queue, false, consumer)
    while (true) {
      val delivery = consumer.nextDelivery()
      val msg = new String(delivery.getBody())
      context.actorOf(Queue2.props(msg))
      channel.basicAck(delivery.getEnvelope.getDeliveryTag, false)
    }
  }
}

0 个答案:

没有答案