Где и как использовать актеров на практике

Как актеры могут быть использованы в сложных серверных службах, которые сделаны из получения первоначального запроса, выполнения некоторой обработки, затем отправки некоторых запросов / вещей в другие службы, ожидания ответов от некоторых из них и принятия решения о том, как продолжить на основе ответов и так далее, пока мы не вычислим окончательный результат?

Попытка использовать акторов для реализации таких сервисов поднимает вопрос: какие части этого рабочего процесса должны реализовываться субъектами, а какие - нет?

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

Этот иерархический дизайн также соответствует шаблону ядра ошибки.

Но это звучит как очень плохо для параллелизма.

И даже если вы попытаетесь сохранить эту иерархию актеров, но оберните вызовы для каждого актера в будущем (не спрашивая, а попросив дочерних актеров), блокировка будет намного короче (хотя она все еще будет существовать) - все еще работает с таким количеством Futures невозможно работать с субъектами с состоянием или с субъектами, которые изменяют состояние системы способами, которые сами не синхронизируются (т.е. не просто изменяют базу данных, что, по крайней мере, для простых запросов выполняется автоматически через базу данных). транзакция - но, скорее, изменение некоторой глобальной переменной в приложении).

Так должны ли актеры использоваться только на нижних уровнях рабочего процесса?

Или же рабочий процесс, который в основном является иерархическим (и большинство из них), будет переписан более последовательным способом, поэтому он не потребует так много уровней дочерних акторов (но это было бы довольно сложно и неестественно, и, похоже, также предоставляет структуру реализации) большое влияние на дизайн).

Это будет означать, что вы признаете, что действующие лица весьма ограничены, и что отказоустойчивость должна в основном обрабатываться традиционной обработкой исключений, и в любом случае желание иметь отказоустойчивое приложение не должно иметь такого большого влияния на дизайн приложение. В таком случае, зачем беспокоиться об актерах? Работать со структурой, требующей чтения реализации каждого субъекта, чтобы понять рабочий процесс сложного спагетти-подобного узла сообщений, гораздо проще, чем работать со структурами, основанными на иерархической структуре, которая может быть раскрыта в любой желаемой степени глядя на сигнатуры методов, не обязательно вглядываясь в их реализацию.

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

1 ответ

Я думаю, что ваше понимание "блокировки" у актеров неверно.

Ты пишешь

но, с другой стороны, он будет поддерживать до N-1 потоков (на первый запрос) - постоянно блокируется, ничего не делая

Неясно, какой сценарий вы описываете здесь. Количество используемых потоков определяется не количеством акторов или слоев в вашей иерархии акторов, но диспетчером, на котором вы запускаете своих актеров, см. https://doc.akka.io/docs/akka/2.5/dispatchers.html?language=scala

Актер обычно не создает новый поток и не блокирует ничего, когда он находится в режиме ожидания. Он обработает (настраиваемое) количество сообщений, а затем вернет управление диспетчеру. Таким образом, с точки зрения многопоточности, Akka, в отличие от того, что вы подозреваете, чрезвычайно эффективна.

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

Там должно быть какое-то недопонимание. Актер, который отправляет сообщение другому, не будет блокировать поток. Непонятно, на какую "блокировку" вы ссылаетесь. Кроме того, предположение, что ask делает блокировку короче, то есть недостатки, очевидно, так как блокировки нет.

Может быть, вас беспокоит использование блокировки ввода-вывода от актеров? Это действительно заблокирует исполняющий поток. "Хитрость" здесь заключается в том, чтобы поместить блокирующие вызовы в отдельного диспетчера, см. https://doc.akka.io/docs/akka/snapshot/dispatchers.html?language=scala

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