Подтвердить что ты не робот

Когда использовать Актеры против Фьючерса?

В настоящее время я работаю над Play! проект, который имеет следующую архитектуру:

Контроллеры → Услуги (участники) → Модели (классы обычных случаев)

Для каждого входящего запроса мы вышлем вызов слоям службы следующим образом:

Service ? DoSomething(request, context)

У нас есть определенное количество этих участников службы за маршрутизатором akka, которые создаются во время инициализации приложения и расширяются по требованию.

И в сервисе мы в основном выполняем скромные манипуляции с данными или вызовы базы данных:

receive = {
    case DoSomething(x, y) => {
           ...
           Model.doSometing(...)
           sender ! result
    }
}

У меня есть вторая мысль о том, следует ли нам использовать актеров для наших услуг или просто использовать только фьючерсы.

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

  • Мы делаем много задач, которые, кажется, сильно уходят от модели актера.

  • Мы не выполняем тяжелые вычисления, а отдаление не имеет смысла, потому что большая часть работы связана с базой данных и обращением к удаленному актеру, чтобы сделать какой-то вызов db ненужным.

  • Мы используем reactivemongo, поэтому каждый вызов db не блокируется. Мы можем сделать много этих звонков

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

4b9b3361

Ответ 1

Конечно, нет недостатка в мнении о том, что должно и не должно быть актером. Как и эти два сообщения:

http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/

http://www.chrisstucchio.com/blog/2013/actors_vs_futures.html

Я не думаю, что вы найдете абсолютный ответ на этот вопрос, а затем, что он ситуационный, и это действительно зависит от ваших предпочтений и вашей проблемы. То, что я могу сделать для вас, - это предложить мое мнение, основанное на том, что мы реализуем Akka около 2 лет.

Для меня мне нравится думать о Акке как о платформе. Мы приходим за моделью Actor, но остаемся для всего остального, что платформа предоставляет как Clustering/Remoting, FSM, Routing, Circuit Breaker, Throttling и тому подобное. Мы пытаемся построить SOA-архитектуру с нашими актерами, выступающими в качестве сервисов. Мы развертываем эти службы по всему кластеру, поэтому мы используем такие функции, как "Прозрачность местоположения" и "Маршрутизация", чтобы предоставить возможность потребителю услуг (который сам может быть другой услугой) для поиска и использования службы независимо от того, где она развернута, и весьма доступным образом. Akka делает весь этот процесс довольно простым, основываясь на инструментах платформы, которые они предлагают.

В нашей системе у нас есть концепция того, что я называю Foundation Services. Это действительно простые службы (например, базовые службы поиска/управления для конкретного объекта). Эти службы обычно не вызывают никаких других сервисов, а в некоторых случаях просто выполняют поиск БД. Эти службы объединены (маршрутизатор) и обычно не имеют состояния. Они довольно похожи на то, что вы описываете некоторыми своими услугами. Затем мы начинаем строить все более сложные услуги поверх этих базовых услуг. Большинство из этих услуг недолговечны (чтобы избежать запроса), иногда на основе FSM, которые собирают данные из услуг фонда, а затем хрустят и что-то делают в результате. Несмотря на то, что эти базовые услуги сами по себе довольно просты, а некоторые, скажем, не требуют актера, мне нравится гибкость в том, что когда я компоную их в сервисе более высокого уровня, я могу найти их, и они могут быть где угодно (местоположение прозрачно ) в моем кластере с любым количеством доступных экземпляров (маршрутизация) для использования.

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

Ответ 2

Я думаю, что ты на правильном пути.

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

Я нашел блог Chris Stucchio (упомянутый выше на @cmbaxter) мгновенно восхитительный. Мое дело было настолько простым, что архитектурные соображения были недействительными. Просто рассыпная маршрутизация и много доступа к базе данных, как и у вас. Нет государства. Таким образом, будущее. Такой простой код.

Ответ 3

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

Мы создали репозитории, давно живущие актеры, которые мы загрузили в нашем приложении: (FYI, мы используем пятно для нашего доступа к БД, но также имеем аналогичный дизайн для наших потребностей MongoDB)

val subscriptionRepo = context.actorOf(Props(new SubscriptionRepository(appConfig.db)), "repository-subscription")

Теперь мы можем отправить сообщение "Запрос" для данных, например:

класс case SubscriptionsRequested (atDate: ZeroMillisDateTime)

чтобы актер ответил

case class SubscriptionsFound(users: Seq[UserSubscription])

или Отказ (исключение)

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

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

Благодаря этому дизайну у нас есть очень реактивный репозиторий, живущий вне нашего приложения, полностью протестированный с помощью Akka TestKit и H2, полностью агрегированный DB, и он мертв легко, чтобы получить доступ к данным из наших БД (и мы никогда не делаем ASK, only Tell: Tell to repo, сообщить отправителю, заполнить или x Сообщает в repos, соответствие шаблону по ожидаемым результатам до завершения, сообщите отправителю).