Nats Java Clientでメッセージを公開および受信する
1. 概要
このチュートリアルでは、Java Client for NATsを使用してNATS Serverに接続し、メッセージを公開および受信します。
NATSは、メッセージ交換の3つの主要なモードを提供します。 Publish/Subscribe semantics delivers messages to all subscribers of a topic. Request/Reply messaging sends requests via topics and routes responses back to the requestor.
サブスクライバーは、トピックをサブスクライブするときにメッセージキューグループに参加することもできます。 関連トピックに送信されたメッセージは、キューグループ内の1人のサブスクライバーにのみ配信されます。
2. セットアップ
2.1. メーベン依存
まず、NATSライブラリをpom.xml:に追加する必要があります
io.nats
jnats
1.0
ライブラリcan be found hereの最新バージョンであり、Githubプロジェクトはhereです。
2.2. NATSサーバー
次に、メッセージを交換するためのNATSサーバーが必要です。 すべての主要なプラットフォームの手順がありますhere.
localhost:4222で実行されているサーバーがあると想定しています。
3. メッセージの接続と交換
3.1. NATSに接続する
静的NATSクラスのconnect()メソッドは、Connectionsを作成します。
デフォルトオプションを使用して接続を使用し、ポート4222でローカルホストをリッスンする場合は、デフォルトの方法を使用できます。
Connection natsConnection = Nats.connect();
ただし、Connectionsには多くの構成可能なオプションがあり、そのうちのいくつかをオーバーライドする必要があります。
Optionsオブジェクトを作成し、それをNatsに渡します。
private Connection initConnection() {
Options options = new Options.Builder()
.errorCb(ex -> log.error("Connection Exception: ", ex))
.disconnectedCb(event -> log.error("Channel disconnected: {}", event.getConnection()))
.reconnectedCb(event -> log.error("Reconnected to server: {}", event.getConnection()))
.build();
return Nats.connect(uri, options);
}
NATS Connections are durable. APIは、失われた接続の再接続を試みます。
切断が発生したときと接続が復元されたときに通知するコールバックをインストールしました。 この例ではラムダを使用していますが、単にイベントをログに記録する以上のことを行う必要があるアプリケーションの場合、必要なインターフェースを実装するオブジェクトをインストールできます。
簡単なテストを実行できます。 接続を作成し、60秒間スリープを追加してプロセスを実行し続けます。
Connection natsConnection = initConnection();
Thread.sleep(60000);
これを実行してください。 次に、NATSサーバーを停止してから開始します。
[jnats-callbacks] ERROR com.example.nats.NatsClient
- Channel disconnected: [email protected]
[reconnect] WARN io.nats.client.ConnectionImpl
- couldn't connect to nats://localhost:4222 (nats: connection read error)
[jnats-callbacks] ERROR com.example.nats.NatsClient
- Reconnected to server: [email protected]
コールバックが切断と再接続を記録するのを見ることができます。
3.2. メッセージを購読する
接続ができたので、メッセージ処理に取り組むことができます。
NATSMessageは、bytes[]の配列のコンテナです。 予想されるsetData(byte[])およびbyte[] getData()メソッドに加えて、メッセージの宛先を設定および取得し、トピックに返信するためのメソッドがあります。
Strings.であるトピックをサブスクライブします
NATSは、同期サブスクリプションと非同期サブスクリプションの両方をサポートします。
非同期サブスクリプションを見てみましょう。
AsyncSubscription subscription = natsConnection
.subscribe( topic, msg -> log.info("Received message on {}", msg.getSubject()));
APIは、スレッド内のMessageHandler(),にMessagesを配信します。
一部のアプリケーションでは、代わりにメッセージを処理するスレッドを制御する場合があります。
SyncSubscription subscription = natsConnection.subscribeSync("foo.bar");
Message message = subscription.nextMessage(1000);
SyncSubscriptionには、指定されたミリ秒数の間ブロックするブロッキングnextMessage()メソッドがあります。 テストケースをシンプルに保つために、テストには同期サブスクリプションを使用します。
AsyncSubscriptionとSyncSubscriptionの両方に、サブスクリプションを閉じるために使用できるunsubscribe()メソッドがあります。
subscription.unsubscribe();
3.3. メッセージの公開
Messagesの公開は、いくつかの方法で実行できます。
最も単純な方法では、トピックStringとメッセージbytesのみが必要です。
natsConnection.publish("foo.bar", "Hi there!".getBytes());
サイト運営者が返信を希望する場合、またはメッセージの送信元に関する特定の情報を提供する場合は、返信トピックを含むメッセージを送信することもできます。
natsConnection.publish("foo.bar", "bar.foo", "Hi there!".getBytes());
bytesの代わりにMessageを渡すなど、他のいくつかの組み合わせにはオーバーロードもあります。
3.4. 簡単なメッセージ交換
有効なConnectionが与えられると、メッセージ交換を検証するテストを書くことができます。
SyncSubscription fooSubscription = natsConnection.subscribe("foo.bar");
SyncSubscription barSubscription = natsConnection.subscribe("bar.foo");
natsConnection.publish("foo.bar", "bar.foo", "hello there".getBytes());
Message message = fooSubscription.nextMessage();
assertNotNull("No message!", message);
assertEquals("hello there", new String(message.getData()));
natsConnection
.publish(message.getReplyTo(), message.getSubject(), "hello back".getBytes());
message = barSubscription.nextMessage();
assertNotNull("No message!", message);
assertEquals("hello back", new String(message.getData()));
同期サブスクリプションを使用する2つのトピックをサブスクライブすることから始めます。これらのトピックはJUnitテスト内でより適切に機能するためです。 次に、一方にメッセージを送信し、もう一方をreplyToアドレスとして指定します。
最初の宛先からメッセージを読んだ後、トピックを「フリップ」して応答を送信します。
3.5. ワイルドカードサブスクリプション
NATSサーバーはトピックワイルドカードをサポートしています。
ワイルドカードは、「..」文字で区切られたトピックトークンで動作します。 アスタリスク文字「*」は、個々のトークンに一致します。 大なり記号â€〜>は、トピックの残りのワイルドカード一致であり、複数のトークンである場合があります。
例えば:
-
foo。*はfoo.bar、foo.requests、but not foo.bar.requestsと一致します
-
foo。>は、foo.bar、foo.requests、foo.bar.requests、foo.bar.exampleなどに一致します。
いくつかのテストを試してみましょう。
SyncSubscription fooSubscription = client.subscribeSync("foo.*");
client.publishMessage("foo.bar", "bar.foo", "hello there");
Message message = fooSubscription.nextMessage(200);
assertNotNull("No message!", message);
assertEquals("hello there", new String(message.getData()));
client.publishMessage("foo.bar.plop", "bar.foo", "hello there");
message = fooSubscription.nextMessage(200);
assertNull("Got message!", message);
SyncSubscription barSubscription = client.subscribeSync("foo.>");
client.publishMessage("foo.bar.plop", "bar.foo", "hello there");
message = barSubscription.nextMessage(200);
assertNotNull("No message!", message);
assertEquals("hello there", new String(message.getData()));
4. Request/Reply Messaging
メッセージ交換テストは、pub / subメッセージングシステムの一般的なイディオムに似ていました。要求/応答。 NATS has explicit support for this request/reply messaging。
パブリッシャーは、上記で使用した非同期サブスクリプションメソッドを使用して、リクエストのハンドラーをインストールできます。
AsyncSubscription subscription = natsConnection
.subscribe("foo.bar.requests", new MessageHandler() {
@Override
public void onMessage(Message msg) {
natsConnection.publish(message.getReplyTo(), reply.getBytes());
}
});
または、到着したリクエストに応答できます。
APIはrequest()メソッドを提供します:
Message reply = natsConnection.request("foo.bar.requests", request.getBytes(), 100);
このメソッドは、応答用の一時メールボックスを作成し、返信先アドレスを書き込みます。
Request()は応答を返し、要求がタイムアウトした場合はnullを返します。 最後の引数は待機するミリ秒数です。
要求/応答のテストを変更できます。
natsConnection.subscribe(salary.requests", message -> {
natsConnection.publish(message.getReplyTo(), "denied!".getBytes());
});
Message reply = natsConnection.request("salary.requests", "I need a raise.", 100);
assertNotNull("No message!", reply);
assertEquals("denied!", new String(reply.getData()));
5. メッセージキュー
サブスクライバーは、サブスクリプション時にキューグループを指定できます。 When a message is published to the group NATS will deliver it to a one-and-only-one subscriber。
Queue groups do not persist messages.使用可能なリスナーがない場合、メッセージは破棄されます。
5.1. キューへのサブスクライブ
サブスクライバーは、キューグループ名をString:として指定します
SyncSubscription subscription = natsConnection.subscribe("topic", "queue name");
もちろん非同期バージョンもあります:
SyncSubscription subscription = natsConnection
.subscribe("topic", "queue name", new MessageHandler() {
@Override
public void onMessage(Message msg) {
log.info("Received message on {}", msg.getSubject());
}
});
サブスクリプションは、NATSサーバーにキューを作成します。
5.2. キューへの公開
キューグループにメッセージを公開するには、関連するトピックへの公開が必要です。
natsConnection.publish("foo", "queue message".getBytes());
NATSサーバーはメッセージをキューにルーティングし、メッセージ受信者を選択します。
テストでこれを確認できます。
SyncSubscription queue1 = natsConnection.subscribe("foo", "queue name");
SyncSubscription queue2 = natsConnection.subscribe("foo", "queue name");
natsConnection.publish("foo", "foobar".getBytes());
List messages = new ArrayList<>();
Message message = queue1.nextMessage(200);
if (message != null) messages.add(message);
message = queue2.nextMessage(200);
if (message != null) messages.add(message);
assertEquals(1, messages.size());
1つのメッセージのみを受信します。
最初の2行を通常のサブスクリプションに変更する場合:
SyncSubscription queue1 = natsConnection.subscribe("foo");
SyncSubscription queue2 = natsConnection.subscribe("foo");
メッセージは両方のサブスクライバーに配信されるため、テストは失敗します。
6. 結論
この簡単な紹介では、NATSサーバーに接続し、pub / subメッセージと負荷分散キューメッセージの両方を送信しました。 ワイルドカードサブスクリプションのNATSサポートを検討しました。 また、リクエスト/リプライメッセージングも使用しました。
いつものように、コードサンプルはover on GitHubで見つけることができます。