[英]Java, Akka Actor and Bounded Mail Box
I have the following configuration in application.conf
: 我在
application.conf
有以下配置:
bounded-mailbox {
mailbox-type = "akka.dispatch.BoundedMailbox"
mailbox-capacity = 100
mailbox-push-timeout-time = 3s
}
akka {
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = INFO
daemonic = on
}
This is the way how I configured my actor 这就是我配置演员的方式
public class MyTestActor extends UntypedActor implements RequiresMessageQueue<BoundedMessageQueueSemantics>{
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String){
Thread.sleep(500);
System.out.println("message = " + message);
}
else {
System.out.println("Unknown Message " );
}
}
}
Now this is how I initate this actor: 现在这就是我如何启动这个actor:
myTestActor = myActorSystem.actorOf(Props.create(MyTestActor.class).withMailbox("bounded-mailbox"), "simple-actor");
After it, in my code I'm sending 3000 messages to this actor. 在它之后,在我的代码中我向这个演员发送了3000条消息。
for (int i =0;i<3000;i++){
myTestActor.tell(guestName, null);}
What I expect to see is the exception that my Queues are full, but my messages are printed inside onReceive method every half second, like nothing happened. 我期望看到的是我的队列已满的例外情况,但我的消息每半秒打印在一次onReceive方法中,就像什么也没发生一样。 So I believe my mailbox configuration is not applied.
所以我认为我的邮箱配置没有应用。
What am I doing wrong? 我究竟做错了什么?
Updated: I created actor which subscribes to dead letter events: 更新:我创建了订阅死信事件的演员:
deadLetterActor = myActorSystem.actorOf(Props.create(DeadLetterMonitor.class),"deadLetter-monitor");
and installed Kamon for queues monitoring: 并安装Kamon进行队列监控:
After sending 3000 messages sent to the actor, Kamin shows me the following: 在向演员发送3000条消息后,Kamin向我展示了以下内容:
Actor: user/simple-actor
MailBox size:
Min: 100
Avg.: 100.0
Max: 101
Actor: system/deadLetterListener
MailBox size:
Min: 0
Avg.: 0.0
Max: 0
Actor: system/deadLetter-monitor
MailBox size:
Min: 0
Avg.: 0.0
Max: 0
By default Akka discards overflowing messages into DeadLetters and actor doesn't stop processing: https://github.com/akka/akka/blob/876b8045a1fdb9cdd880eeab8b1611aa976576f6/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala#L411 默认情况下,Akka将溢出的消息丢弃到DeadLetters中并且actor不会停止处理: https : //github.com/akka/akka/blob/876b8045a1fdb9cdd880eeab8b1611aa976576f6/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala# L411
But sending thread will be blocked on interval which is configured by mailbox-push-timeout-time
before discarding the message. 但是在丢弃消息之前,发送线程将被阻塞,该间隔由
mailbox-push-timeout-time
配置。 Try to decrease it to 1ms and see that following test will pass: 尝试将其减少到1毫秒,并看到以下测试将通过:
import java.util.concurrent.atomic.AtomicInteger
import akka.actor._
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory._
import org.specs2.mutable.Specification
class BoundedActorSpec extends Specification {
args(sequential = true)
def config: Config = load(parseString(
"""
bounded-mailbox {
mailbox-type = "akka.dispatch.BoundedMailbox"
mailbox-capacity = 100
mailbox-push-timeout-time = 1ms
}
"""))
val system = ActorSystem("system", config)
"some messages should go to dead letters" in {
system.eventStream.subscribe(system.actorOf(Props(classOf[DeadLetterMetricsActor])), classOf[DeadLetter])
val myTestActor = system.actorOf(Props(classOf[MyTestActor]).withMailbox("bounded-mailbox"))
for (i <- 0 until 3000) {
myTestActor.tell("guestName", null)
}
Thread.sleep(100)
system.shutdown()
system.awaitTermination()
DeadLetterMetricsActor.deadLetterCount.get must be greaterThan(0)
}
}
class MyTestActor extends Actor {
def receive = {
case message: String =>
Thread.sleep(500)
println("message = " + message);
case _ => println("Unknown Message")
}
}
object DeadLetterMetricsActor {
val deadLetterCount = new AtomicInteger
}
class DeadLetterMetricsActor extends Actor {
def receive = {
case _: DeadLetter => DeadLetterMetricsActor.deadLetterCount.incrementAndGet()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.