Когда использовать актеров вместо решений для обмена сообщениями, таких как WebSphere MQ или Tibco Rendezvous?
Я уже читал вопрос и ответы на него. Какие дизайнерские решения предпочтут актеры Scala вместо JMS?,
Обычно мы используем решения для обмена сообщениями, которые существуют уже в течение многих лет: либо реализация JMS, такая как WebSphere MQ или Apache ActiveMQ, используется для связи точка-точка, либо Tibco Rendevous для многоадресной передачи сообщений.
Они очень стабильны, проверены и предлагают высокую доступность и производительность. Тем не менее, настройка и настройка кажутся гораздо более сложными, чем в Akka.
Когда и почему я должен использовать Akka для некоторых случаев, когда вышеупомянутые продукты - WebSphere MQ или ActiveMQ - до сих пор успешно использовались? Почему я должен рассмотреть возможность использования Akka вместо WebSphere MQ или Tibco RV в моем будущем проекте?
И когда я должен избегать Akka? Обеспечивает ли он ту же высокую доступность и производительность, что и другие решения? Или это плохая идея даже сравнивать Akka с другим промежуточным программным обеспечением для обмена сообщениями?
Может быть, есть и другое решение для обмена сообщениями в среде JVM, которое я должен рассмотреть, кроме JMS (точка-точка), TibcoRV (многоадресная передача) и Akka?
4 ответа
Прежде всего, "старые" системы сообщений (MQ) являются более старыми в реализации, но они являются более новой в инженерной идее: постоянные транзакционные очереди. Scala Actors и Akka, возможно, более новая реализация, но построены на более старой модели параллелизма Actors.
Однако две модели на практике оказываются очень похожими, поскольку обе они основаны на сообщениях о событиях: см. Мой ответ на RabbitMQ против Akka.
Если вы собираетесь писать код только для JVM, тогда, вероятно, Akka - хороший выбор. В противном случае я бы использовал RabbitMQ.
Кроме того, если вы разработчик Scala, тогда Akka должна быть легкой задачей. Однако Java-привязки Akka не очень Java-иш и требуют приведения из-за системы типов Scala.
Также в Java люди обычно не создают неизменных объектов, которые я рекомендую вам делать для обмена сообщениями. Следовательно, в Java очень легко случайно сделать что-то, используя Akka, который не будет масштабироваться (используя изменяемые объекты для сообщений, полагаясь на странное закрытое состояние обратного вызова). С MQ это не проблема, потому что сообщения всегда сериализуются за счет скорости. С аккой их вообще нет.
Акка также масштабируется лучше с большим количеством потребителей, чем большинство 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, и простая-реакция.
Выбор правильной модели / библиотеки параллелизма очень важен для приложений с низкой задержкой. Решение распределенной обработки, такое как очередь сообщений, как правило, не является идеальным, поскольку маршрутизация почти всегда выполняется по проводной линии, которая, очевидно, медленнее, чем внутри приложения, и, следовательно, Akka будет лучшим выбором. Однако я считаю, что некоторые проприетарные технологии MQ допускают локальную маршрутизацию. Также, как я упоминал ранее, большинство клиентов MQ довольно глупы в отношении потоков и не полагаются на неблокирующие операции ввода-вывода и имеют потоки на соединение / очередь / канал... по иронии судьбы неблокируемый ввод-вывод не всегда имеет низкую задержку, но обычно требует больше ресурсов эффективный.
Как вы можете видеть, тема распределенного программирования и параллельного программирования довольно обширна и меняется каждый день, поэтому мое первоначальное намерение не было сбить с толку, а скорее сосредоточиться на одной конкретной области распределенной обработки сообщений, которая, как я думал, касалась ОП. С точки зрения параллелизма можно было бы сосредоточить свои поиски на "реактивном" программировании (RFP / потоки), которое является "более новой", но аналогичной моделью для модели субъекта и модели очереди сообщений, в которой все эти модели могут быть в целом объединены, поскольку они основаны на событиях.
Я не специалист по системам обмена сообщениями, но вы можете комбинировать их с Akka в своих приложениях, получая лучшее из обоих миров. Вот пример, который может оказаться полезным для экспериментов с Akka и системами обмена сообщениями, в данном случае ZeroMQ:
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 с 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);
}
}
Я не очень хорошо знаком с упомянутыми инструментами, но знаком с основными концепциями разработки программного обеспечения. Поэтому я думаю, что дело в единственном ключе к принятию решения: децентрализации. Я имею в виду, что помимо распространения, которое все XXX - MQ и Akka (как компоненты архитектуры передачи сообщений) могут привнести в ваше приложение, есть еще одна возможность, называемая децентрализацией. Но поскольку в большинстве случаев использования децентрализацию и распределение можно свести друг к другу, то обоснованность такого опроса в вашем случае следует сначала перепроверить. Затем спросите себя, обрабатывая требования к передаче сообщений, какой из одноранговых или одноранговых узлов соответствует вашим потребностям.
Akka выполняет работу по принципу «одноранговый узел», поэтому предлагает децентрализованное решение, но другие упомянутые инструменты предлагают централизованные решения. В качестве поясняющего примера рассмотрим реализацию сети, требующей архитектуры передачи сообщений, такой как Биткойн. Akka способна поддерживать такой вариант использования, но другие упомянутые инструменты не сработают. Все остальные упомянутые инструменты также поддерживают архитектуру передачи сообщений, но ни один из них, кроме Akka, не может поддерживать требования децентрализации Биткойна.