113

JMS の代わりに Scala のアクターを優先する設計上の決定は何ですか?の質問と回答を既に読みました。.

通常、私たちは何年も前から存在するメッセージング ソリューションを使用します。WebSphere MQ や Apache ActiveMQ などの JMS 実装がポイント ツー ポイント通信に使用されるか、Tibco Rendevous がマルチキャスト メッセージングに使用されます。

それらは非常に安定しており、実績があり、高い可用性とパフォーマンスを提供します。それにもかかわらず、構成とセットアップは Akka よりもはるかに複雑に見えます。

前述の製品 (WebSphere MQ または ActiveMQ) がこれまで正常に使用されてきた場合に、いつ、どのような理由で Akka を使用する必要がありますか? 今後のプロジェクトで WebSphere MQ や Tibco RV の代わりに Akka の使用を検討する必要があるのはなぜですか?

そして、いつAkkaを避けるべきですか?他のソリューションと同じ高可用性とパフォーマンスを提供しますか? それとも、Akka を他のメッセージング ミドルウェアと比較することさえ悪い考えですか?

JVM 環境には、JMS (ポイントツーポイント)、TibcoRV (マルチキャスト)、Akka 以外に検討すべき別のメッセージング ソリューションがあるのではないでしょうか?

4

3 に答える 3

96

まず、「古い」メッセージ システム (MQ) は実装が古いですが、トランザクションの永続キューというエンジニアリングの考え方は新しいものです。Scala アクターと Akka はおそらく新しい実装ですが、古いアクターの同時実行モデルに基づいて構築されています。

ただし、2 つのモデルはどちらもイベント メッセージ ベースであるため、実際には非常に似ています。RabbitMQ と Akkaに対する私の回答を参照してください。

JVM のみをコーディングする場合は、おそらく Akka を選択することをお勧めします。それ以外の場合は、RabbitMQ を使用します。

また、Scala 開発者であれば、Akka は簡単に使用できるはずです。ただし、Akka の Java バインディングはあまり Java らしくなく、Scala の型システムのためにキャストが必要です。

また、Java では、人々は通常、メッセージングのために行うことをお勧めする不変オブジェクトを作成しません。その結果、Java では、スケーリングしない Akka を使用して誤って何かを行うのは非常に簡単です (メッセージに変更可能なオブジェクトを使用し、奇妙なクロージャー コールバック状態に依存します)。MQ では、メッセージは常に速度を犠牲にしてシリアル化されるため、これは問題ではありません。Akka では、一般的にそうではありません。

また、Akka は、ほとんどの MQ よりも大量のコンシューマーに対してより適切にスケーリングします。これは、ほとんどの MQ (JMS、AMQP) クライアントでは、すべてのキュー接続にスレッドが必要なためです。したがって、多数のキュー == 永続的に実行される多数のスレッドになります。ただし、これは主にクライアントの問題です。ActiveMQ Apollo には、AMQP の問題を修正するというノンブロッキング ディスパッチャがあると思います。RabbitMQ クライアントには、複数のコンシューマーを組み合わせることができるチャネルがありますが、多数のコンシューマーがデッドロックや接続の停止を引き起こす可能性があるという問題がまだ残っているため、通常、この問題を回避するためにスレッドが追加されます。

そうは言っても、Akka のリモーティングはかなり新しいものであり、おそらく、従来のメッセージ キューが提供するすべての信頼できるメッセージ保証と QoS をまだ提供していません (ただし、これは日々変化しています)。それも一般的にピアツーピアですが、ほとんどのMQシステムが一般的に行うサーバーツーピア(つまり、単一障害点)をサポートしていると思いますが、ピアツーピアのMQシステムがあります(RabbitMQはサーバーです-じっと見ます)。

最後に、RabbitMQ と Akka は実際に良い組み合わせになります。特に、RabbitMQ はメッセージの消費を処理し、メッセージをローカルに (単一の JVM で) ルーティングするのに役立たないため、RabbitMQ のラッパーとして Akka を使用できます。

Akka を選択する場合

  • 多くの消費者がいます (数百万と考えてください)。
  • 低遅延が必要
  • アクター同時実行モデルに対応

サンプル システム: インタラクティブなリアルタイム チャット システム

MQ を選択する場合

  • 多くの異なるシステムと統合する必要がある (つまり、非 JVM)
  • メッセージの信頼性は遅延よりも重要です
  • より多くのツールと管理 UI が欲しい
  • 以前のポイントにより、長時間実行されるタスクに適しています
  • アクターとは異なる同時実行モデルを使用したい

サンプル システム: スケジュールされたトランザクション バッチ処理システム

関係するコメントに基づいて編集

OP は、 Akkaと Message Queuesの両方が処理できる分散処理に関係していると仮定しました。つまり、彼は分散 Akkaについて話していると思いました。ローカル コンカレンシーに Akka を使用することは、ほとんどのメッセージ キューと比較して非常に簡単です。Reactorライブラリとsimple-reactの両方が行う同時実行モデル (つまり、トピック、キュー、交換) としてメッセージ キュー モデルをローカルに適用できるためです。

適切な同時実行モデル/ライブラリを選択することは、低レイテンシ アプリケーションにとって非常に重要です。メッセージ キューなどの分散処理ソリューションは一般的に理想的ではありません。これは、ほとんどの場合ルーティングがネットワーク経由で行われるため、アプリケーション内よりも明らかに遅いため、Akka が優れた選択肢となるからです。ただし、一部の独自の MQ テクノロジでは、ローカル ルーティングが可能になっていると思います。また、前述したように、ほとんどの MQ クライアントはスレッド化についてかなり愚かであり、ノンブロッキング IO に依存せず、接続/キュー/チャネルごとにスレッドを持っています...皮肉なことに、ノンブロッキング IO は常に低レイテンシであるとは限りませんが、一般的により多くのリソースです。効率的。

ご覧のとおり、分散プログラミングと並行プログラミングのトピックはかなり大きく、毎日変化しているため、当初の意図は混乱ではなく、OP が関心を持っていた分散メッセージ処理の特定の領域に焦点を当てることでした。並行性に関しては、「リアクティブ」プログラミング (RFP / ストリーム) に検索の焦点を当てたいと思うかもしれません。これは「新しい」モデルですが、アクター モデルとメッセージ キュー モデルに似ています。イベントベースです。

于 2012-10-22T19:15:42.280 に答える
4

私はメッセージング システムの専門家ではありませんが、アプリケーションでそれらを Akka と組み合わせて、両方の長所を活かすことができます。以下は、Akka とメッセージング システム (この場合は ZeroMQ) を試すのに役立つと思われる例です。

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

于 2011-04-17T13:03:45.013 に答える
1

Akka-Camel は ZeroMQ よりも良い例です。ZeroMQ は tcp から tcp への直接通信です (したがって、ゼロ - メッセージ キューはありません)。

AkkaCamel を使用すると、キューを抽象化し、メッセージ キュー メッセージのプッシュ/プルを処理するコードなしで、アクターから直接メッセージを生成/消費できます。

akka-zeromq をやめて、Akka をリモートで直接使用できます。akka-zeromq はコア ライブラリから削除されていると思いますが、scala-zeromq という akka 用の優れた zeromq ライブラリを作成しました ( https://github.com/mDialog/scala-zeromq )

Akka にはいくつかの重要なコア ユース ケースがあります。

1) 可変状態

アクターに非表示にすることで、共有状態を処理しやすくなります。アクターはメッセージを同期的に処理するため、アクターで状態を保持し、アクター API を介して高い一貫性でそのフィールドを公開できます。

2) 配布

akka では並行性が無料なので、分散の問題を解決するためのものだとおっしゃっています。マシンとコア全体への分散。Akka には、ネットワーク経由でメッセージを送信するための「場所の透過性」が組み込まれています。単一のサービスをスケールアップするためのクラスタリングとパターンも関連付けられています。これにより、配布用の非常に優れたソリューションになります (マイクロサービス アーキテクチャなど)。

これは、Akka-Camel (Java8 を使用) を使用した ActiveMQ で Akka を使用する例です。

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);

    }
}
于 2014-12-13T20:52:45.177 に答える