我目前正在从事使用akka 2.4的项目。该项目是使用akka DistributedPubSub介体编写的。在初始测试阶段,一切似乎都工作正常,但是随着我们现在的规模扩展,我们经常看到Distributed PubSub中介程序发布和订阅服务中的内存消耗非常大。发布服务会很快填满内存,并停止处理更多消息。
发布服务的application.conf是:
akka {
loggers = ["de.heikoseeberger.akkalog4j.Log4jLogger"]
logging-filter = "de.heikoseeberger.akkalog4j.Log4jLoggingFilter"
loglevel = debug
log-dead-letters = off
actor {
provider = "akka.cluster.ClusterActorRefProvider"
serializers {
java = "akka.serialization.JavaSerializer"
}
serialization-bindings {
"java.lang.String" = java
}
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "<IP>"
port =2551
}
}
cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@<InternalIP1>:2551",
"akka.tcp://ClusterSystem@<InternalIP2>:2551"]
# auto downing is NOT safe for production deployments.
# you may want to use it during development, read more about it in the docs.
#
auto-down-unreachable-after = 10s
pub-sub {
removed-time-to-live = 120s
}
}
}
akka.cluster.metrics.enabled=true
akka.extensions=["akka.cluster.pubsub.DistributedPubSub","akka.cluster.client.ClusterClientReceptionist"]
发布者代码如下:
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof InitializeLogger) {
getSender().tell(Logging.loggerInitialized(), getSelf());
} else if (message instanceof MemberUp) {
MemberUp mUp = (MemberUp) message;
LOGGER.trace("Member is Up: {}", mUp.member());
} else if (message instanceof UnreachableMember) {
UnreachableMember mUnreachable = (UnreachableMember) message;
LOGGER.trace("Member detected as unreachable: {}", mUnreachable.member());
} else if (message instanceof MemberRemoved) {
MemberRemoved mRemoved = (MemberRemoved) message;
LOGGER.trace("Member is Removed: {}", mRemoved.member());
} else if (message instanceof MemberEvent) {
// ignore
} else if (message instanceof Message) {
LOGGER.info("Obtained a message in message type{}", message);
// counter.increment();
mediator.tell(new DistributedPubSubMediator.Publish(TOPIC_NAME, message), getSelf());
} else
unhandled(message);
}
问题1:因为我们使用的是默认邮箱(即无限制队列),所以邮箱消息在被订阅者角色消费后是否可能没有被清除? 。如果是这样,我该如何清除它们。我以为“删除时间”将清除这些消息,但我认为我的理解是错误的。
在运行在单独节点上的订户端,我有一个参与者订阅了主题并使用消息。该演员充当委派者,并对另一个本地演员执行“讲述”。 订户应用程序conf如下:
akka {
loglevel = "INFO"
log-dead-letters = off
log-dead-letters-during-shutdown = off
actor {
provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "InternalIP1"
port = 2551
}
}
cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@<InternalIP1>:2551"
"akka.tcp://ClusterSystem@<InternalIP2>:2551"
]
auto-down-unreachable-after = 120s
}
blocking-io-dispatcher = "akka.stream.default-blocking-io-dispatcher"
akka.extensions=["akka.cluster.client.ClusterClientReceptionist"]
default-blocking-io-dispatcher {
type = "Dispatcher"
executor = "thread-pool-executor"
throughput = 1
thread-pool-executor {
core-pool-size-min = 2
core-pool-size-factor = 2.0
core-pool-size-max = 16
}
}
akka.remote.transport-failure-detector.acceptable-heartbeat-pause = 10s
}
问题2:在执行本地“告诉”操作时,我发现在处理消息方面存在巨大的时间滞后(接近7分钟)。我认为这是因为加载了订户actor的邮箱(我们也为订户使用了默认邮箱,这是一个无界队列。)。我们看到订户也慢慢地开始消耗内存。邮件耗尽后,如何确保清除邮箱。
现在,我们已经开始重新启动服务,这是清除邮箱的一种非常粗糙且不正确的方法。为了避免此内存泄漏,我在配置中缺少什么。
如果有人可以就此问题提供帮助,我们将不胜感激。