Когда использовать акторов вместо решений для обмена сообщениями, таких как WebSphere MQ или Tibco Rendezvous?


106

Я уже читал вопрос и ответы на вопрос, какие проектные решения предпочтительнее для Scala Actors вместо JMS? .

Обычно мы используем решения для обмена сообщениями, которые существуют уже много лет: либо реализация JMS, такая как WebSphere MQ или Apache ActiveMQ, используется для связи точка-точка, либо Tibco Rendevous для многоадресной передачи сообщений.

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

Когда и почему мне следует использовать Akka в некоторых случаях, когда вышеупомянутые продукты - WebSphere MQ или ActiveMQ - уже успешно используются? Почему мне следует рассмотреть возможность использования Akka вместо WebSphere MQ или Tibco RV в моем будущем проекте?

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

Может быть, в среде JVM есть еще одно решение для обмена сообщениями, которое я должен рассмотреть помимо JMS (Point-to-Point), TibcoRV (Multicast) и Akka?


2

Ответы:


92

Во-первых, «старые» системы сообщений (MQ) старше по реализации, но они новее в инженерной идее: постоянные очереди транзакций . Scala Actors и Akka, возможно, являются более новой реализацией, но построены на более старой модели параллелизма Actors.

Однако на практике эти две модели очень похожи, поскольку обе основаны на сообщениях о событиях: см. Мой ответ на RabbitMQ vs Akka .

Если вы собираетесь писать код только для JVM, тогда Akka, вероятно, будет хорошим выбором. В противном случае я бы использовал RabbitMQ.

Кроме того, если вы разработчик Scala, тогда Akka не должно вызывать проблем. Однако Java-привязки Akka не очень похожи на Java и требуют преобразования из-за системы типов Scala.

Также в Java люди обычно не создают неизменяемые объекты, что я рекомендую вам делать для обмена сообщениями. Следовательно, в Java очень легко случайно сделать что-то с помощью Akka, которое не будет масштабироваться (используя изменяемые объекты для сообщений, полагаясь на странное состояние обратного вызова закрытия). С MQ это не проблема, потому что сообщения всегда сериализуются за счет скорости. С Аккой их вообще нет.

Akka также лучше масштабируется с большим количеством потребителей, чем большинство MQ. Это связано с тем, что для большинства клиентов MQ (JMS, AMQP) каждое соединение очереди требует потока ... таким образом, много очередей == много постоянно работающих потоков. Однако это в основном проблема клиента. Я думаю, что ActiveMQ Apollo имеет неблокирующий диспетчер, который якобы исправляет эту проблему для AMQP. У клиента RabbitMQ есть каналы, которые позволяют объединять несколько потребителей, но по-прежнему существуют проблемы с большим количеством потребителей, которые могут привести к зависанию или отключению соединений, поэтому, как правило, добавляется больше потоков, чтобы избежать этой проблемы.

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

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

Когда выбирать Акка

  • Иметь много потребителей (думаю, миллионы).
  • Требуется низкая задержка
  • Открыт для модели параллелизма акторов

Пример системы: интерактивная система чата в реальном времени.

Когда выбирать MQ

  • Необходима интеграция с множеством разных систем (например, без JVM)
  • Надежность сообщений важнее задержки
  • Хотелось бы больше инструментов и интерфейса администратора
  • Из-за предыдущих пунктов лучше для длительных задач
  • Хотели бы использовать другую модель параллелизма, чем акторы

Пример системы: запланированная система пакетной обработки транзакций

ИЗМЕНИТЬ на основе соответствующих комментариев

Я сделал предположение, что OP был связан с распределенной обработкой, которую могут обрабатывать как Akka, так и очереди сообщений. То есть я предположил, что он имел в виду распределенный Акка . Использование Akka для локального параллелизма - это сравнение яблок с апельсином для большинства очередей сообщений . Я говорю больше, потому что вы можете применить модель очереди сообщений локально как модель параллелизма (то есть тему, очереди, обмены), что и библиотека Reactor, и simple-response .

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

Как вы можете видеть, тема распределенного программирования и параллельного программирования довольно велика и меняется каждый день, поэтому мое первоначальное намерение не было путаницей, а скорее сосредоточилось на одной конкретной области распределенной обработки сообщений, которой, как я думал, занимался OP. Что касается параллелизма, можно сосредоточить свои поиски на «реактивном» программировании (RFP / потоки), которое является «более новой», но похожей моделью на модель актора и модель очереди сообщений, в которых все эти модели могут быть объединены, поскольку они основаны на событиях.


3
Я думаю, что ответ на неправильный вопрос не может быть правильным. Вы не можете сравнивать очередь сообщений и модель параллелизма. Они созданы для решения ПОЛНОСТЬЮ разных задач и имеют общее только слово «сообщение».
Игорь С.

2
Ну да и нет. Akka поддерживает распределенный обмен сообщениями, и вы можете очень легко построить модель параллелизма на основе парадигмы очереди сообщений (Google Spring's Reactor). На самом деле, единственное различие сейчас в том, что RabbitMQ имеет надежные сообщения ... о, подождите, Akka теперь поддерживает и это. Он может сказать «Актер» в названии, но явно указывает на Akka, которая имеет большое совпадение со многими системами на основе сообщений (как параллельных, так и распределенных).
Адам Гент

4
Кстати, @IgorS. Типичная модель параллелизма, используемая с очередями сообщений, называется SEDA (поэтапная архитектура, управляемая событиями). Помимо использования очередей, тем и обменов, это модель параллелизма сама по себе (которая также является распределенной моделью ... точно так же, как модель акторов). Я также очень презираю, когда кто-то говорит «неправильный вопрос» ... помимо неуместных вопросов, когда вопрос может быть неправильным? Язвительно и элитарно говорить что-то подобное.
Адам Гент

1
Я никогда не говорил, что они взаимозаменяемы. Я даже говорю, что они отлично работают вместе и почему. Но он явно говорит здесь о распределенной акка, а не о библиотеке актеров. Вот как я это читал. Не стесняйтесь редактировать мой пост, поскольку ваша точка зрения действительна и может сбить с толку других, кто наткнется на сообщение.
Адам Гент,

1
Один из API Java Akka - теперь он очень чистый, особенно с лямбдами JDK 8. Я подозреваю, что станет лучше, если / когда они введут объекты значений с JDK 10.
Роб Кроуфорд

4

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

https://github.com/zcox/akka-zeromq-java


6
ZeroMQ - это не совсем система обмена сообщениями. Это скорее какие-то усовершенствованные розетки. Полноценные системы обмена сообщениями намного сложнее ZeroMQ. Проект по вашей ссылке кажется лишь тонкой оберткой вокруг ZeroMQ с Akka.
Владимир Матвеев

1

Akka-Camel был бы лучшим примером, чем ZeroMQ - ZeroMQ - это прямая связь tcp с tcp (следовательно, ноль - нет очереди сообщений).

С помощью AkkaCamel вы можете абстрагироваться от очереди и создавать / получать сообщения непосредственно от актера без какого-либо кода для обработки выталкивания / вытягивания сообщений очереди сообщений.

Вы можете отказаться от akka-zeromq и использовать Akka напрямую с удаленным взаимодействием. Я думаю, что akka-zeromq удаляется из основной библиотеки, но мы создали хорошую библиотеку zeromq для akka под названием scala-zeromq ( https://github.com/mDialog/scala-zeromq )

У Akka есть несколько основных вариантов использования:

1) Мутабельное состояние

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

2) Распространение

Параллелизм в akka бесплатен, так что вы говорите, что это действительно решение проблем распространения. Распределение по машинам и ядрам. Akka имеет встроенную «прозрачность местоположения» для отправки сообщений по сети. Он также имеет кластеризацию и шаблоны, связанные для увеличения масштаба отдельной службы. Это делает его очень хорошим решением для распространения (например, микросервисная архитектура).

Вот пример использования Akka с ActiveMQ с Akka-Camel (с использованием Java8)

import akka.actor.Props;
import akka.camel.Camel;
import akka.camel.CamelExtension;
import akka.testkit.TestActorRef;
import akka.testkit.TestProbe;
import org.junit.Ignore;
import org.junit.Test;
import akka.camel.javaapi.UntypedProducerActor;
import akka.camel.javaapi.UntypedConsumerActor;
import static com.rogers.totes.TotesTestFixtures.*;
import org.apache.activemq.camel.component.*;

public class MessagingTest {
    @Test @Ignore
    public void itShouldStoreAMessage() throws Exception{
        String amqUrl = "nio://localhost:61616";
        Camel camel = (Camel) CamelExtension.apply(system);
        camel.context().addComponent("activemq", ActiveMQComponent.activeMQComponent(amqUrl));

        TestProbe probe = TestProbe.apply(system);
        TestActorRef producer = TestActorRef.create(system, Props.create((Producer.class)));
        TestActorRef consumer = TestActorRef.create(system, Props.create((Consumer.class)));
        producer.tell("Produce", probe.ref());

        Thread.sleep(1000);
    }
}

class Producer extends UntypedProducerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }
}

class Consumer extends UntypedConsumerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("GOT A MESSAGE!" + message);

    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.