Распределение сообщения актера потоку диспетчера - PullRequest
0 голосов
/ 21 апреля 2020

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

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

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

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

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

1 Ответ

2 голосов
/ 22 апреля 2020

X-Post с Дискуссионного форума Lightbend: https://discuss.lightbend.com/t/actor-message-allocation-to-dispatcher-thread/6314

Прежде чем я даже начну, короткий ответ "не волнуйтесь об этом". Я понимаю любопытство, но на микроуровне оно будет неопределенным, и на макроуровне единственное, о чем вам нужно заботиться, это документация Диспетчер , такая как разница между обычными диспетчерами, закрепленными диспетчерами, исполнители fork-join и пула потоков, а также в порядке упорядочения в документации Messaging Ordering .

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

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

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

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

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

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

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

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

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

...