Wann sollten Schauspieler anstelle von Messaging-Lösungen wie WebSphere MQ oder Tibco Rendezvous verwendet werden?


106

Ich habe bereits die Frage und die Antworten zu gelesen. Welche Designentscheidungen würden Scalas Schauspieler anstelle von JMS bevorzugen? .

Normalerweise verwenden wir Messaging-Lösungen, die es schon seit Jahren gibt: Entweder wird eine JMS-Implementierung wie WebSphere MQ oder Apache ActiveMQ für die Punkt-zu-Punkt-Kommunikation verwendet, oder Tibco Rendevous für Multicast-Messaging.

Sie sind sehr stabil, bewährt und bieten hohe Verfügbarkeit und Leistung. Trotzdem scheinen Konfiguration und Einrichtung viel komplexer zu sein als in Akka.

Wann und warum sollte ich Akka für einige Anwendungsfälle verwenden, in denen die oben genannten Produkte - WebSphere MQ oder ActiveMQ - bisher erfolgreich eingesetzt wurden? Warum sollte ich in meinem zukünftigen Projekt Akka anstelle von WebSphere MQ oder Tibco RV verwenden?

Und wann sollte ich Akka meiden? Bietet es die gleiche hohe Verfügbarkeit und Leistung wie die anderen Lösungen? Oder ist es eine schlechte Idee, Akka überhaupt mit den anderen Messaging-Middlewares zu vergleichen?

Vielleicht gibt es in der JVM-Umgebung noch eine andere Messaging-Lösung, die ich neben JMS (Punkt-zu-Punkt), TibcoRV (Multicast) und Akka in Betracht ziehen sollte?


Antworten:


92

Zunächst einmal sind die "älteren" Nachrichtensysteme (MQ) in der Implementierung älter, aber sie sind eine neuere technische Idee von: persistenten Transaktionswarteschlangen . Scala Actors und Akka sind möglicherweise eine neuere Implementierung, basieren jedoch auf einem älteren Parallelitätsmodell von Actors.

Die beiden Modelle sind sich jedoch in der Praxis sehr ähnlich, da beide auf Ereignismeldungen basieren: Siehe meine Antwort auf RabbitMQ vs Akka .

Wenn Sie nur für die JVM codieren möchten, ist Akka wahrscheinlich eine gute Wahl. Ansonsten würde ich RabbitMQ verwenden.

Auch wenn Sie ein Scala-Entwickler sind, sollte Akka ein Kinderspiel sein. Akkas Java-Bindungen sind jedoch nicht sehr Java-artig und erfordern aufgrund des Scala-Typsystems ein Casting.

Auch in Java werden normalerweise keine unveränderlichen Objekte erstellt, die ich für Messaging empfehle. Infolgedessen ist es in Java sehr einfach, versehentlich etwas mit Akka zu tun, das nicht skaliert werden kann (unter Verwendung veränderlicher Objekte für Nachrichten, basierend auf dem seltsamen Rückrufstatus beim Schließen). Mit MQ ist dies kein Problem, da die Nachrichten immer auf Kosten der Geschwindigkeit serialisiert werden. Bei Akka sind sie im Allgemeinen nicht.

Akka skaliert auch bei einer großen Anzahl von Verbrauchern besser als die meisten MQ. Dies liegt daran, dass für die meisten MQ-Clients (JMS, AMQP) jede Warteschlangenverbindung einen Thread erfordert ... daher viele Warteschlangen == viele permanent laufende Threads. Dies ist jedoch hauptsächlich ein Kundenproblem. Ich denke, ActiveMQ Apollo hat einen nicht blockierenden Dispatcher, der angeblich dieses Problem für AMQP behebt. Der RabbitMQ-Client verfügt über Kanäle, mit denen Sie mehrere Verbraucher kombinieren können. Es gibt jedoch immer noch Probleme mit einer großen Anzahl von Verbrauchern, die möglicherweise zum Ausfall von Deadlocks oder Verbindungen führen. Daher werden im Allgemeinen mehr Threads hinzugefügt, um dieses Problem zu vermeiden.

That being said Akka des Remoting ziemlich neu ist und wahrscheinlich nicht bieten noch nicht alle zuverlässigen Nachrichten Garantien und QoS , dass die traditionellen Nachrichtenwarteschlangen liefern (aber die jeden Tag ändert). Es ist im Allgemeinen auch Peer-to-Peer, aber ich denke, es unterstützt Server-to-Peer, was im Allgemeinen das ist, was die meisten MQ-Systeme tun (dh Single Point of Failure), aber es gibt MQ-Systeme, die Peer-to-Peer sind (RabbitMQ ist Server-). to-peer).

Schließlich machen RabbitMQ und Akka tatsächlich ein gutes Paar. Sie können Akka als Wrapper für RabbitMQ verwenden, insbesondere da RabbitMQ Ihnen nicht dabei hilft, den Verbrauch von Nachrichten zu handhaben und die Nachrichten lokal (in einer einzelnen JVM) weiterzuleiten.

Wann sollte man Akka wählen?

  • Haben Sie viele Verbraucher (denken Sie Millionen).
  • Benötigen Sie eine geringe Latenz
  • Öffnen Sie das Actor-Parallelitätsmodell

Beispielsystem: Ein interaktives Echtzeit-Chat-System

Wann wählen Sie MQ

  • Notwendigkeit der Integration in viele verschiedene Systeme (dh Nicht-JVM)
  • Die Zuverlässigkeit von Nachrichten ist wichtiger als die Latenz
  • Möchte mehr Tools und Admin-Benutzeroberfläche
  • Wegen vorheriger Punkte besser für lange laufende Aufgaben
  • Möchte ein anderes Parallelitätsmodell als Actors verwenden

Beispielsystem: Ein geplantes Transaktions-Stapelverarbeitungssystem

BEARBEITEN basierend auf betroffenen Kommentaren

Ich ging davon aus, dass sich das OP mit der verteilten Verarbeitung befasst, die sowohl von Akka als auch von Message Queues verarbeitet werden kann. Das heißt, ich nahm an, er sprach über verteilte Akka . Die Verwendung von Akka für die lokale Parallelität ist ein Vergleich zwischen Äpfeln und Orange im Vergleich zu den meisten Nachrichtenwarteschlangen . Ich sage das meiste, weil Sie das Nachrichtenwarteschlangenmodell lokal als Parallelitätsmodell (dh Thema, Warteschlangen, Austausch) anwenden können, das sowohl in der Reactor- Bibliothek als auch einfach reagiert tun.

Die Auswahl des richtigen Parallelitätsmodells / der richtigen Parallelitätsbibliothek ist für Anwendungen mit geringer Latenz sehr wichtig. Eine verteilte Verarbeitungslösung wie eine Nachrichtenwarteschlange ist im Allgemeinen nicht ideal, da das Routing fast immer über das Kabel erfolgt, was offensichtlich langsamer als innerhalb der Anwendung ist und daher Akka eine überlegene Wahl wäre. Ich glaube jedoch, dass einige proprietäre MQ-Technologien lokales Routing ermöglichen. Wie ich bereits erwähnt habe, sind die meisten MQ-Clients ziemlich dumm in Bezug auf Threading und verlassen sich nicht auf nicht blockierende E / A und haben einen Thread pro Verbindung / Warteschlange / Kanal ... ironischerweise ist nicht blockierendes Io nicht immer eine niedrige Latenz, sondern im Allgemeinen mehr Ressource effizient.

Wie Sie sehen, ist das Thema verteilte Programmierung und gleichzeitige Programmierung ziemlich umfangreich und ändert sich täglich. Daher war meine ursprüngliche Absicht nicht verwirrend, sondern konzentrierte sich auf einen bestimmten Bereich der verteilten Nachrichtenverarbeitung, mit dem ich mich im OP befasst habe. In Bezug auf die Parallelität könnte man seine Suche auf "reaktive" Programmierung (RFP / Streams) konzentrieren, die ein "neueres", aber ähnliches Modell wie das Akteurmodell und das Nachrichtenwarteschlangenmodell ist, von denen alle diese Modelle im Allgemeinen kombiniert werden können, weil sie sind ereignisbasiert.


3
Ich denke, eine Antwort auf eine falsche Frage kann nicht richtig sein. Sie können eine Nachrichtenwarteschlange und ein Parallelitätsmodell nicht vergleichen. Sie sind so gebaut, dass sie VOLLSTÄNDIG unterschiedliche Aufgaben lösen und haben nur das Wort "Nachricht" gemeinsam.
Igor S.

2
Na ja und nein. Akka unterstützt verteiltes Messaging und Sie können sehr einfach ein Parallelitätsmodell aus dem Paradigma der Nachrichtenwarteschlange (Google Spring's Reactor) erstellen. Wirklich der einzige Unterschied ist jetzt, dass RabbitMQ dauerhafte Nachrichten hat. Oh, warte, Akka unterstützt das jetzt auch. Er mag im Titel "Schauspieler" sagen, weist aber ausdrücklich auf Akka hin, das sich massiv mit vielen nachrichtenbasierten Systemen (sowohl gleichzeitig als auch verteilt) überschneidet.
Adam Gent

4
Übrigens @IgorS. Das typische Parallelitätsmodell, das mit Nachrichtenwarteschlangen verwendet wird, heißt SEDA (Staged Event Driven Architecture). Neben der Verwendung von Warteschlangen, Themen und Börsen handelt es sich um ein Parallelitätsmodell an sich (das zufällig auch ein verteiltes Modell ist, genau wie das Akteurmodell). Ich verachte es auch sehr, wenn jemand "falsche Frage" sagt. Abgesehen von unangemessenen Fragen, wann kann eine Frage falsch sein? Es ist bissig und elitär, so etwas zu sagen.
Adam Gent

1
Ich habe nie gesagt, dass sie austauschbar sind. Ich sage sogar, dass sie großartig zusammenarbeiten und warum. Aber er spricht hier eindeutig von verteiltem Akka und nicht von Akka, der Schauspielerbibliothek. So habe ich es gelesen. Fühlen Sie sich frei, meinen Beitrag zu bearbeiten, da Ihr Punkt gültig ist und andere verwirren könnte, die über den Beitrag stolpern.
Adam Gent

1
Eine der Akka Java APIs - sie ist jetzt sehr sauber, insbesondere mit JDK 8 Lambdas. Ich vermute, es wird besser, wenn sie Wertobjekte mit JDK 10 einführen.
Rob Crawford

4

Ich bin kein Experte für Messaging-Systeme, aber Sie können sie mit Akka in Ihren Apps kombinieren, um das Beste aus beiden Welten zu erhalten. Hier ist ein Beispiel, das Sie möglicherweise zum Experimentieren mit Akka- und Messagingsystemen nützlich finden, in diesem Fall ZeroMQ:

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


6
ZeroMQ ist nicht gerade ein Nachrichtensystem. Es ist eher eine Art verbesserte Steckdosen. Vollwertige Messagingsysteme sind viel komplexer als ZeroMQ. Das Projekt unter Ihrem Link scheint nur eine dünne Hülle um ZeroMQ mit Akka zu sein.
Vladimir Matveev

1

Akka-Camel wäre ein besseres Beispiel als ZeroMQ - ZeroMQ ist eine direkte Kommunikation von TCP zu TCP (daher Null - es gibt keine Nachrichtenwarteschlange).

Mit AkkaCamel können Sie die Warteschlange abstrahieren und Nachrichten direkt von einem Akteur ohne Code produzieren / konsumieren, um das Drücken / Ziehen von Nachrichten in der Nachrichtenwarteschlange zu verarbeiten.

Sie können auf akka-zeromq verzichten und Akka direkt mit Remoting verwenden. Ich denke, akka-zeromq wird aus der Kernbibliothek entfernt, aber wir haben eine gute zeromq-Bibliothek für akka namens scala-zeromq erstellt ( https://github.com/mDialog/scala-zeromq) ).

Akka hat einige wichtige Anwendungsfälle:

1) Veränderlicher Zustand

Es ist einfacher, mit dem gemeinsamen Status umzugehen, indem Sie ihn in einem Schauspieler verstecken. Da Akteure Nachrichten synchron verarbeiten, können Sie den Status in einem Akteur halten und dieses Feld über die Akteur-API mit hoher Konsistenz verfügbar machen

2) Verteilung

Parallelität ist in akka kostenlos, Sie sagen also, es geht wirklich darum, Verteilungsprobleme zu lösen. Verteilung über Maschinen und Kerne. Akka hat "Standorttransparenz" für das Senden von Nachrichten über das Kabel eingebaut. Es sind Clustering und Muster zugeordnet, um auch einen einzelnen Dienst zu skalieren. Dies macht es zu einer sehr guten Lösung für den Vertrieb (z. B. Micro-Service-Architektur).

Hier ist ein Beispiel für die Verwendung von Akka mit ActiveMQ mit Akka-Camel (mit 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);

    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.