Что такое фреймворк Akka? Когда мне его использовать?

Здравствуйте, коллеги-разработчики!
Мы все хотим создать модель параллельного программирования, но с помощью Spring мы можем сделать только очень многое. Разработка параллельного приложения затруднена, потому что нам нужно иметь дело с синхронизацией, блокировками и общей памятью. Давайте посмотрим, как Akka может помочь нам в создании модели параллелизма.

Akka Введение

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

Spring фокусируется на «водопроводе» корпоративных приложений, чтобы разработчики могли сосредоточиться на бизнес-логике на уровне приложений, без ненужных привязок к конкретным средам развертывания. В то время как Akka использует модель субъектов и обеспечивает уровень абстракции, который упрощает написание правильных параллельных, параллельных и распределенных систем.

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

Akka очень стабильна, и решение let-it-crash + supervisor до отказа действительно работает хорошо. Его легко настроить, и модульное тестирование также довольно просто.

Akka предоставляет:

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

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

<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-actor_2.12</artifactId>
    <version>2.5.26</version>
</dependency>

Какие актеры в Akka?

Как мы обсуждали выше, вся структура akka вращается вокруг актеров. Актер - это контейнер для Состояние, Поведение, Почтовый ящик, Дочерние актеры и Стратегия супервизора, каждый из этих акторов всегда принадлежит родителю, и создание актера возвращает ссылку, которая является действительным URL-адресом. Мы можем создать актера, вызвав ActorContext.spawn(). Актер-создатель становится родительским для вновь созданного дочернего субъекта. У всех участников есть общий родитель, опекун пользователя, который определяется и создается при запуске ActorSystem.

Akka уже создала в системе двух участников. Имена этих встроенных субъектов содержат опекун. Актеры-хранители включают:

  • актор root Guardian имеет адрес «/», который представляет собой корень иерархии системы акторов.
  • субъект опекуна пользователя имеет адрес «/ user». Это будет родитель всех определяемых нами акторов.
  • субъект системного опекуна имеет адрес «/ system». Это будет родитель для всех акторов, определенных внутри системы Akka.

Как создать актера

Нам нужно создать систему акторов перед тем, как создавать актеров.

ActorSystem system = ActorSystem.create("my-system");

Просто при создании системы акторов по умолчанию создаются 3 субъекта: root, пользователь и системный хранитель.

Классы акторов реализуются путем расширения класса AbstractActor и установки «начального поведения» в методе createReceive. Props - это класс конфигурации, чтобы указать параметры для создания субъектов, мы можем настроить такие вещи, как диспетчер, почтовый ящик или конфигурацию развертывания. Этот класс неизменяемый, поэтому потокобезопасный. Метод createReceive() обрабатывает входящие сообщения от других субъектов.

Актер принимает сообщение типа String, как указано в match из ReceiveBuilder, поэтому этому субъекту могут быть отправлены только сообщения типа String, и, если отправлены какие-либо другие типы, они перейдут в мертвые буквы. Чтобы использовать другие типы классов, мы можем добавить несколько match случаев, определяющих эти классы объектов в качестве типов ввода.

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

ActorRef myActorRef = system.actorOf(MyActor.props(), "myActor");

Общение между актерами

Акторы общаются друг с другом с помощью сообщений, эти сообщения могут быть объектами любого типа с условием, что они неизменны.
Системные сообщения акторов Akka отправляются с использованием методов:

  • tell () - Операция «сказать» - это запустить и забыть, мы отправляем сообщение асинхронно и переходим к следующему этапу.
myActorRef.tell("Hello Actor", ActorRef.noSender());
  • ask () - «попросив» другого субъекта предоставить некоторую информацию, мы вернем Future, которое в конечном итоге может быть завершено. Это будущее завершается, когда принимающий субъект отправляет сообщение обратно отправителю.
CompletableFuture<Object> future = ask(myActorRef, 
  "Please reply", 1000).toCompletableFuture();

В классе MyActor мы используем getSender().tell(“Hello Sender”, getSelf());, который отправит сообщение обратно отправителю.

  • forward () - операция «пересылки» не изменяет отправителя сообщений. Исходный адрес / ссылка отправителя сохраняется, даже если сообщение проходит через «посредника». Это может быть полезно при написании акторов, которые работают как маршрутизаторы, балансировщики нагрузки, репликаторы и т. Д.
myActorRef.forward("forward this message", getContext());

Как убить актера

Stop
Мы можем убить актера, используя его ActorRef в ActorRefFactory, просто вызвав метод stop в ActorSystem и передав ссылку на актера, который нужно остановить, как Аргумент.

system.stop(myActorRef);

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

myActorRef.tell(PoisonPill.getInstance(), ActorRef.noSender());

Убить
Мы также можем «убить» актера, отправив Kill сообщение. В отличие от PoisonPill, это заставит актера выбросить ActorKilledException, вызывая сбой. Субъект приостановит работу, и его супервизору будет предложено, как справиться с ошибкой, что может означать возобновление действия субъекта, его перезапуск или полное прекращение.

myActorRef.tell(Kill.getInstance(), ActorRef.noSender());

Graceful Stop
Мы можем использовать gracefulStop, если нам нужно дождаться завершения или составить упорядоченное завершение нескольких акторов.

CompletionStage<Boolean> stopped =
      gracefulStop(myActorRef, Duration.ofSeconds(5), Manager.SHUTDOWN);

Когда gracefulStop() возвращается успешно, будет выполнен postStop() хук актера: между концом postStop() и возвращением gracefulStop() существует граница "произошло раньше".

Kill Parent
Если мы убиваем родительского актора, он посылает сигнал уничтожения всем дочерним актерам, порожденным им.

Завершение системы-актора
Когда система акторов больше не нужна, мы можем завершить ее, чтобы освободить все ресурсы и предотвратить любые утечки памяти:

Future<Terminated> terminateResponse = system.terminate();

Это подводит итог основам Akka Framework и Actor System. Если вы сочтете это полезным, пожалуйста, отпустите несколько аплодисментов и не стесняйтесь поделиться им. Это подписка Винеша. Пока