По умолчанию все актеры Akka используют одного исполнителя, который ограничен использованием максимум 64 потоков. С https://doc.akka.io/docs/akka/current/general/configuration-reference.html:
# This will be used if you have set "executor = "default-executor"".
# If an ActorSystem is created with a given ExecutionContext, this
# ExecutionContext will be used as the default executor for all
# dispatchers in the ActorSystem configured with
# executor = "default-executor". Note that "default-executor"
# is the default value for executor, and therefore used if not
# specified otherwise. If no ExecutionContext is given,
# the executor configured in "fallback" will be used.
default-executor {
fallback = "fork-join-executor"
}
и fork-join-executor
config:
# This will be used if you have set "executor = "fork-join-executor""
# Underlying thread pool implementation is java.util.concurrent.ForkJoinPool
fork-join-executor {
# Min number of threads to cap factor-based parallelism number to
parallelism-min = 8
# The parallelism factor is used to determine thread pool size using the
# following formula: ceil(available processors * factor). Resulting size
# is then bounded by the parallelism-min and parallelism-max values.
parallelism-factor = 1.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 64
# Setting to "FIFO" to use queue like peeking mode which "poll" or "LIFO" to use stack
# like peeking mode which "pop".
task-peeking-mode = "FIFO"
}
Проблема может быть связана с блокировкой вызовов в субъектах процессора. Akka назначает отдельные потоки из пула 64 для обработки этих блокирующих вызовов в субъектах процессора и ожидает, пока один из них завершит обработку сообщений, чтобы иметь возможность обрабатывать сообщения для других участников. Это может вызвать временную задержку между актерами.
Ключевой аспект, на котором основывается Akka, заключается в том, что системы должны постоянно реагировать. Если вы использовали тот же пул диспетчера / потока для блокирующих операций БД или обработки сообщений, что и основная инфраструктура маршрутизации Akka, вполне возможно, что все потоки Akka могут быть заняты субъектами обработки или операциями БД, и ваша система будет фактически заблокирована. пока одна из операций блокировки не будет завершена. Это может не быть проблемой для простой системы на одной JVM, которая выполняет только эту задачу, но когда она масштабируется, это может вызвать много проблем.
В таких случаях, как ваша, где вы не можете избежать блокировки, следует использовать выделенный диспетчер для операций блокировки. Эта ссылка говорит об этом аспекте (хотя он называется Akka-Http, его можно обобщить). Вы можете создать два типа диспетчеров для обработки двух разных операций блокировки. Я также считаю, что вам следует регулировать запросы на блокировку, чтобы не перегружать вашу систему (для регулирования используйте диспетчеры). Вы также можете использовать буферы внутри ваших акторов для работы с ситуациями обратного давления.
EDIT
Почтовый ящик контроллера содержит 100 сообщений, и 5 сообщений принимаются и делегируются субъектам процессора. Каждый субъект процессора занимает 2 минуты времени и отправляет ответ обратно контроллеру, а ответ помещается в очередь в почтовом ящике контроллера. Но перед обработкой этих сообщений контроллер должен обработать сообщения, которые были добавлены до того, как эти сообщения эффективно увеличат время обслуживания для обработки сообщений для контроллера. Лаг является кульминацией всего этого процесса. Как только контроллер получил ответное сообщение, он делегировался субъекту. Я думаю, что время обработки сообщений увеличивается с увеличением.
Дайте мне знать, если это поможет !!