Выделение сообщения актора потоку диспетчера

Известно, что потоки Dispatcher отвечают за выполнение сообщений актора. Используя параметр пропускной способности, мы можем определить no. сообщений, обработанных потоком диспетчера перед переходом к другому субъекту

Но я не уверен, как поток диспетчера выберет актера?

Скажем, я создал 10 000 акторов, в которых только 1000 акторов одновременно получают сообщения, а остальные 9000 акторов бездействуют, а количество потоков диспетчера равно 200.

В каком порядке поток диспетчера будет выбирать сообщение актера. Будет ли он проверять почтовый ящик неактивных участников и сообщения?

Может ли кто-нибудь объяснить поток, в котором поток диспетчера выбирает сообщения почтового ящика актера.

1 ответ

Решение

X-сообщение с форума Lightbend Discuss: https://discuss.lightbend.com/t/actor-message-allocation-to-dispatcher-thread/6314

Еще до того, как я начну, короткий ответ - "не беспокойтесь об этом". Я понимаю любопытство, но на микроуровне это будет неопределенным, а на макроуровне единственное, о чем вам нужно позаботиться, это в документации Dispatcher, например, разница между обычными диспетчерами, закрепленными диспетчерами, fork-join и thread исполнителей пула и в гарантиях заказа в документации по заказу сообщений.

Кроме того, отказ от ответственности, я не утверждаю, что являюсь экспертом по внутреннему устройству диспетчеров: я всего лишь конечный пользователь. Но я немного откладывал и решил, что поделюсь некоторыми своими наблюдениями за настройкой и немного пощупаю исходный код Akka для развлечения. Для более подробных ответов вы также должны посмотреть исходный код. Большинство ответов, которые вы ищете, будут находиться в папке akka -actor / src / main / scala / akka / dispatch.

Убрав этот отказ от ответственности, позвольте мне сначала ответить на ваш второй вопрос.

"Будет ли [диспетчер] проверять почтовый ящик незанятых акторов также на наличие сообщений?"

Диспетчер на самом деле ничего не проверяет: он полностью реагирует. (Как мы увидим позже.) Это, конечно, не тратит время на проверку пустых почтовых ящиков. Вот почему один диспетчер может масштабироваться до миллионов участников.

Ваш более общий вопрос "как поток диспетчера выберет актера?" гораздо труднее ответить простым способом. Есть очень много типов диспетчеров. И почти каждый ответ, который я могу вам дать, будет исключением. (Например, вышеупомянутый закрепленный диспетчер, в котором потоки выделены для определенных субъектов, и CallingThreadDispatcher, который предназначен для тестирования и выполняет все вызовы в текущем потоке). Но позвольте мне поговорить о типичных диспетчерах при типичных обстоятельствах.

Диспетчеры не выбирают субъектов, диспетчеры (в типичном случае) просто взаимодействуют с Java ExecutorServices. Типичный сценарий выглядит так:

  • Вы добавляете сообщение в почтовый ящик Актера. (С точки зрения диспетчера мы имеем перевернутый взгляд на мир: мы взаимодействуем с почтовым ящиком, а не с актером.)
  • Если почтовый ящик еще не запланирован (что может уже быть, если в нем есть сообщения), почтовый ящик отправляется своему диспетчеру и планирует себя.
  • Диспетчер переходит к базовому ExecutorService (скажем, ForkJoinExecutor) и ставит задачу для обработки почтового ящика.
  • Java ForkJoinExecutor - сложная часть планирования, и я не претендую на роль эксперта. Но краткая версия заключается в том, что каждый поток имеет свою собственную очередь, но способен "красть" задачи из других очередей, когда у него есть пустая очередь. Реализация Java также имеет возможность динамически регулировать количество используемых потоков до предела параллелизма. Вот почему я сказал "на микроуровне" это неопределенно. Кража работы динамических потоков очень эффективна, но не детерминирована.
  • В какой-то момент задача, связанная с почтовым ящиком, содержащим сообщение, будет выбрана исполнителем и будет вызван Runnable..
  • Runnable будет сначала обрабатывать системные сообщения в почтовом ящике, а затем обычные сообщения. Здесь тоже есть всевозможные исключения, такие как приоритетные почтовые ящики, тайники, ограничения пропускной способности и т. Д., Но в целом почтовый ящик будет обрабатывать сообщения (используя поведение актора) до тех пор, пока почтовый ящик не опустеет или не будет достигнут один из пределов пропускной способности. Обратите внимание, что задача привязана к почтовому ящику, а не к сообщению.

Вышеизложенное упрощено и игнорирует некоторые крайние случаи и оптимизацию производительности, но это 30000 футов.

Я надеюсь, что это поможет, потому что я знаю, что он наполнен исключениями (почтовые ящики и диспетчеры разработаны так, чтобы быть гибкими) и сложным. Но Akka очень оптимизирован и безумно эффективен. Если кто-то из разработчиков Akka захочет вмешаться, скажет мне, где я сделал неаккуратное описание, не стесняйтесь. Но конечный результат - это то, с чего я начал: здесь есть несколько уровней абстракции, поэтому единственные гарантии заказа, которые вы получаете, - это те, которые задокументированы, но общая пропускная способность системы чрезвычайно эффективна, даже если работа, выполняемая на одно сообщение, небольшая, а количество сообщений огромный.

Другие вопросы по тегам