Apache Tribes - イントロダクション

目次

クイックスタート

Apache Tribesは、グループまたはピアツーピア通信フレームワークであり、リモートオブジェクトを簡単に接続して相互に通信できるようにします。

  • インポート: org.apache.catalina.tribes.Channel
  • インポート: org.apache.catalina.tribes.Member
  • インポート: org.apache.catalina.tribes.MembershipListener
  • インポート: org.apache.catalina.tribes.ChannelListener
  • インポート: org.apache.catalina.tribes.group.GroupChannel
  • org.apache.catalina.tribes.ChannelListenerを実装するクラスを作成します。
  • org.apache.catalina.tribes.MembershipListenerを実装するクラスを作成します。
  • メッセージの送信方法を示す簡単なクラス
    //create a channel
    Channel myChannel = new GroupChannel();
    
    //create my listeners
    ChannelListener msgListener = new MyMessageListener();
    MembershipListener mbrListener = new MyMemberListener();
    
    //attach the listeners to the channel
    myChannel.addMembershipListener(mbrListener);
    myChannel.addChannelListener(msgListener);
    
    //start the channel
    myChannel.start(Channel.DEFAULT);
    
    //create a message to be sent, message must implement java.io.Serializable
    //for performance reasons you probably want them to implement java.io.Externalizable
    Serializable myMsg = new MyMessage();
    
    //retrieve my current members
    Member[] group = myChannel.getMembers();
    
    //send the message
    myChannel.send(group,myMsg,Channel.SEND_OPTIONS_DEFAULT);

シンプルですよね? Tribesにはここで示したもの以外にも多くの機能があります。ドキュメントで詳しく説明されていることを願っています。ご提案、改善、バグ修正など、このプロジェクトに役立つと思われるものはいつでも歓迎します。

Tribesとは

Tribesは、グループ通信機能を備えたメッセージングフレームワークです。Tribesを使用すると、ネットワーク経由でメッセージを送受信したり、ネットワーク内の他のノードを動的に検出したりできます。
これが簡単な説明です。本当にこれほどシンプルです。Tribesの有用性と独自性については、以下のセクションで説明します。

Tribesモジュールは2006年初頭に開始され、コードベースの一部は2003年または2004年から存在するクラスタリングモジュールからのものです。現在のクラスタ実装にはいくつかの欠点があり、グループ通信の複雑さのために多くの回避策が作成されました。端的に言って、ずっと前に2つのモジュールであるべきだったものが、今になります。Tribesは、レプリケーションモジュールからメッセージングの複雑さを排除し、完全に独立した非常に柔軟なグループ通信モジュールになります。

Tomcatでは、古いmodules/clustermodules/groupcom(Tribes)とmodules/ha(レプリケーション)になりました。これにより、開発を進め、開発者が興味のないモジュールの詳細に悩まされることなく、実際に取り組んでいる問題に集中できます。通信とレプリケーションはどちらも十分に複雑であり、同じモジュールで開発しようとすると、ご存知のとおり、クラスタになります:)

Tribesは、保証されたメッセージングを可能にし、さまざまな方法でカスタマイズできます。なぜこれが重要なのですか?
開発者として、送信しているメッセージが宛先に届いていることを知りたいと思うでしょう。さらに、メッセージが宛先に届かない場合、Tribes上のアプリケーションは、メッセージが送信されなかったこと、およびどのノードで失敗したかを通知されます。

なぜ別のメッセージングフレームワークなのか

私はコードの再利用を強く推奨しており、他の誰かがすでに開発していて、私と私がサービスを提供しようとしているコミュニティが利用できる場合、何かを開発することを夢にも思いません。
クラスタリングモジュールを改善するための調査を行ったとき、私は常にいくつかの障害に直面していました。
1. フレームワークが十分に柔軟ではない
2. フレームワークは、私とコミュニティのどちらも使用できない方法でライセンスされていました
3. 必要な機能がいくつか不足していた
4. メッセージングは保証されていましたが、フィードバックは報告されませんでした
5. メッセージ配信のセマンティクスは、実行前に構成する必要がありました
そしてリストは続きます...

そこで、これらの問題やその他の問題に対処するために、Tribesを考案しました。Tribesを設計する際には、既存のフレームワークがすでに提供している柔軟性と配信セマンティクスのいずれも失わないようにしたかったのです。目標は、他のフレームワークがすでに実行しているすべてのことを実行できるが、アプリケーション開発者により多くの柔軟性を提供するフレームワークを作成することでした。次のセクションでは、Tribesが提供する、または提供する予定の機能の概要を説明します。

機能概要

機能セットのアイデアを提供するために、ここにリストします。機能の一部はまだ完成していません。その場合は、それに accordingly マークが付けられています。

プラグイン可能なモジュール
Tribesはインターフェースを使用して構築されています。Tribesの一部であるモジュールまたはコンポーネントは、独自のTribes実装をカスタマイズするためにスワップアウトできます。

保証されたメッセージング
Tribesのデフォルト実装では、メッセージングにTCPまたはUDPを使用します。TCPには、メッセージ配信の保証とフロー制御がすでに組み込まれています。Java TCPのパフォーマンスは、ロジックがスタックのさらに下で行われるため、Java / UDP /フロー制御/メッセージ保証の実装よりも優れていると信じています。UDPメッセージングは、必要に応じてTCPの代わりにUDP経由でメッセージを送信するために追加されました。以下で説明するのと同じ保証シナリオはUDPでも使用できますが、UDPメッセージが失われた場合は失敗と見なされます。
Tribesは、非ブロッキングIO操作とブロッキングIO操作の両方をサポートしています。推奨設定は、メッセージの送受信時に並列処理が向上するため、非ブロッキングを使用することです。ブロッキング実装は、NIOがまだ問題のあるプラットフォームで使用できます。

さまざまな保証レベル
メッセージが送信されるときの配信保証には、3つの異なるレベルがあります。

  1. IOベースの送信保証。- 最速、信頼性が低い
    これは、メッセージがソケット送信バッファに送信され、受け入れられた場合、Tribesはメッセージ転送が成功したと見なすことを意味します。
    ブロッキングIOでは、これはsocket.getOutputStream().write(msg)になります
    非ブロッキングIOでは、これはsocketChannel.write()になり、バッファバイトバッファが空になり、続いてsocketChannel.read()が実行されてチャネルがまだ開いていることを確認します。NIOを使用している場合、接続が「閉じられた」場合でもwrite()が成功するため、read()が追加されました。
  2. ACKベース。- 推奨、配信保証
    メッセージがリモートノードで受信されると、メッセージが正常に受信されたことを示すACKが送信者に送り返されます。
  3. SYNC_ACKベース。- 配信保証、処理保証、最遅
    メッセージがリモートノードで受信されると、ノードはメッセージを処理し、メッセージが正常に処理された場合、メッセージが正常に受信および処理されたことを示すACKが送信者に送り返されます。メッセージが受信されたが、処理に失敗した場合、ACK_FAILが送信者に送り返されます。これは、アプリケーション開発者に非常に大きな価値を追加するユニークな機能です。ほとんどのフレームワークはここで、メッセージが配信されたことを通知し、アプリケーション開発者は、リモートノードのアプリケーションによってメッセージが実際に正しく処理されたかどうかについてのロジックを組み込む必要があります。設定されている場合、TribesはACK_FAILを受信すると例外をスローし、その例外をメッセージを処理しなかったメンバーに関連付けます。

もちろん、さらに洗練された保証レベルを作成することもできます。その一部については、ドキュメントの後半で説明します。言及できるレベルの1つは、2フェーズコミットです。リモートアプリケーションは、すべてのノードがメッセージを受信するまでメッセージを受信しません。一種のall-or-nothingプロトコルのようなものです。

メッセージごとの配信属性
おそらく、Tribesをグループ通信フレームワークの群衆から際立たせる機能です。Tribesを使用すると、メッセージ転送がメッセージごとにどのような配信セマンティクスを持つべきかを決定できます。つまり、メッセージは、メッセージフレームワークが開始された後に固定されたままの静的構成に基づいて配信されません。
この機能がどれほど強力かを示すために、簡単な例で説明してみます。10個の異なるメッセージを送信する必要があると想像してみてください。次の方法で送信できます。

Message_1 - asynchronous and fast, no guarantee required, fire and forget
Message_2 - all-or-nothing, either all receivers get it, or none.
Message_3 - encrypted and SYNC_ACK based
Message_4 - asynchronous, SYNC_ACK and call back when the message is processed on the remote nodes
Message_5 - totally ordered, this message should be received in the same order on all nodes that have been
            send totally ordered
Message_6 - asynchronous and totally ordered
Message_7 - RPC message, send a message, wait for all remote nodes to reply before returning
Message_8 - RPC message, wait for the first reply
Message_9 - RPC message, asynchronous, don't wait for a reply, collect them via a callback
Message_10- sent to a member that is not part of this group

もうお分かりのように、これらはほんの一例です。メッセージごとに適用できるセマンティクスの数はほぼ無制限です。Tribesでは、メッセージに最大28個の異なる設定を設定し、Tribesを構成して、どのフラグがメッセージのどのアクションになるかを決定できます。
共有トランザクショナルキャッシュを想像してみてください。おそらく90%以上は読み取りであり、ダーティ読み取りは完全に順序付けされていないため、できるだけ早く配信する必要があります。しかし、一方、トランザクショナル書き込みは、キャッシュが破損しないように順序付ける必要があります。Tribesを使用すると、書き込みメッセージは完全に順序付けられますが、読み取りメッセージは最高のスループットを実現するために単純に送信されます。
この強力な機能の使用方法についてはおそらくもっと良い例があるので、想像力と経験を使って、これがアプリケーションにどのように役立つかを考えてみてください。

インターセプターベースのメッセージ処理
Tribesは、カスタマイズ可能なインターセプタースタックを使用して、送受信されるメッセージを処理します。
だから何?すべてのフレームワークにこれがあります!
はい、しかしTribesでは、インターセプターは、実行時に送信されるメッセージごとの属性に基づいてメッセージに反応できます。つまり、メッセージを暗号化する暗号化インターセプターを追加する場合、このインターセプターがすべてのメッセージを暗号化するか、Tribes上で実行されているアプリケーションによって決定される特定のメッセージのみを暗号化するかを決定できます。
Tribesが一部のメッセージを完全に順序付けして送信し、他のメッセージを上記の例のようにfire-and-forgetスタイルで送信できるのはこのためです。
利用可能なインターセプターの数は増え続けており、皆様からの貢献を賜りたく存じます。

スレッドレスインターセプタースタックインターセプターは、メッセージ操作を実行するために個別のスレッドを必要としません。
送信されるメッセージは、送信中のスレッドに便乗して送信されます。例外はMessageDispatchInterceptorです。これは、メッセージをキューに入れ、非同期メッセージ配信のために別のスレッドで送信します。受信されたメッセージは、receiverコンポーネントのスレッドプールによって制御されます。
チャネルオブジェクトは、インターセプタースタックを介してheartbeat()を送信することで、タイムアウト、クリーンアップ、その他のイベントを処理できます。
MessageDispatchInterceptorは、デフォルトで設定されている唯一のインターセプターです。

並列配信
Tribesはメッセージの並列配信をサポートしています。つまり、node_Aはnode_Bに3つのメッセージを並行して送信できます。この機能は、異なる配信セマンティクスを持つメッセージを送信する場合に役立ちます。そうでない場合、Message_1が完全順序で送信された場合、Message_2はそのメッセージが完了するまで待機する必要があります。
NIO を使用することで、Tribes は同じスレッド上で複数の受信者に同時にメッセージを送信できます。

サイレントメンバーメッセージング
Tribesを使用すると、自分のグループに属していないメンバーにメッセージを送信できます。そのため、デフォルトでは、ワイドエリアネットワークを介してメッセージを送信できます。現在の動的検出モジュールは、動的ノード検出にマルチキャストを使用することでローカルエリアネットワークに制限されていますが、将来的には、メンバーシップコンポーネントはWANメンバーシップをサポートするように拡張される予定です。しかし、これは、グループの他のメンバーからメンバーを隠蔽し、それらのメンバーとのみ通信する場合に非常に役立ちます。

Tribesはどこで入手できますか

TribesはTomcatのモジュールとして提供され、Apache Tomcatリリースの一部としてリリースされます。