前のチュートリアルでは、簡単なロギングシステムを構築しました。私たちは、放送多数の受信者にメッセージをログに記録することができます。
このチュートリアルでは、機能を追加します - 我々は唯一の可能性であるサブ統合メッセージにサブスクライブします。例えば、我々はまだ、コンソール上のすべてのログメッセージを印刷することができながら、(ディスクスペースを節約するために)、ログファイルにのみ致命的なエラー・メッセージを送信することができるようになります。
1、結合
前の例では、結合を作成する必要があります。あなたはこのコードを考えるかもしれません。
channel.queueBind(queueName, EXCHANGE_NAME, "");
バインディングは、Exchangeとキューとの間の関係です。これは次のように簡単に読み取ることができる:キューからのメッセージは、Exchangeを買いました。
追加的に結合するために使用することができroutingKey
、パラメータを。避けるためにbasic_publish
混乱引数を、我々はそれを呼ばれますbinding key
。ここでは、バインドを作成するためにキーを使用する方法です。
channel.queueBind(queueName, EXCHANGE_NAME, "black");
つまり、キーバインディングは、Exchangeの種類によって異なります。私たちは、以前に使用ファンアウトスイッチ、その値を無視します。
2、直接交換
前のチュートリアルで、我々はすべての消費者にブロードキャストすべてのシステムメッセージをログに記録します。私たちは、その重大度に基づいてフィルタのメッセージを許可するようにして展開します。例えば、我々は、ディスクに書き込まれたメッセージを記録しますだけではなく警告または情報レベルのログメッセージにディスクスペースを無駄にするよりも、重大なエラーを受け取るためのプログラムをお勧めします。
我々は以前にファンアウトスイッチを使用し、それは私たちに多くの柔軟性を与えていない - それが機能のみを放送することができます。
ここでは、ダイレクトスイッチを使用します。この背後にルーティングアルゴリズムの直接交換が簡単です-メッセージはに送信されますbinding key
メッセージrouting key
キー完全一致キュー。
この点を説明するには、次の設定を考えてみます。
この設定では、Xと2つのキューの直接交換が一緒にバインドされて見ることができます。バインディングキーバインディングオレンジとの最初のキューは、2番目のキューは、二つの結合キー、キーバインディング他の緑と黒を持っています。
このような構成では、ルーティングキーを使用して、パブリッシャへメッセージオレンジスイッチQ1は、キューにルーティングされます。緑や黒のメッセージルーティングキーでQ2を移動します。他のすべてのメッセージは破棄されます。
3、複数のバインディング
複数のキューと同じバインドキーバインドを完全に許可されています。この例では、XとQ1の間に黒のキーバインディングを追加することができます。この場合、直接交換スイッチの振る舞いは、一致するすべてのキューにファンアウト、およびブロードキャストメッセージが好き。黒鍵付きメッセージルーティングは、Q1とQ2に送られます。
4、送信ログ
我々は、ログシステムでは、このモデルを使用します。私たちは、むしろファンアウト・スイッチを使用するよりも、スイッチを指示するメッセージを送信します。私たちは、主要ルートとしてログレベルを提供します。このように、受信プログラムは、それが受信したいというログレベルを選択することができます。私たちは最初のリリースログを集中してみましょう。
いつものように、我々はスワップを作成する必要があります。
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
私たちは、メッセージを送信する準備ができています:
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
簡単にするために、我々は、ログのレベルが「情報」、「警告」、「エラー」であることを仮定します。
5、サブスクライブ
一つの例外を除いて、前のチュートリアルと同じ動作するメッセージを受信する - 私たちが興味を持っているログレベルは、我々は新しいバインディングを作成します。
String queueName = channel.queueDeclare().getQueue();
for(String severity : argv){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
EmitLogDirect.java
public class EmitLogDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.20.128");
factory.setPort(5672);
factory.setUsername("carl");
factory.setPassword("198918");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
Map<String, String> logs = new HashMap<String, String>();
logs.put("info", "this is a info message");
logs.put("error", "this is a error message");
logs.put("warning", "this is a warning message");
Set<Map.Entry<String, String>> entries = logs.entrySet();
for (Map.Entry<String, String> entry : entries) {
channel.basicPublish(EXCHANGE_NAME, entry.getKey(), null, entry.getValue().getBytes("UTF-8"));
System.out.println(" [x] Sent '" + entry.getKey() + "':'" + entry.getValue() + "'");
}
channel.close();
connection.close();
}
}
EmitLogDirect.java
メッセージのログレベルを送信するプロバイダーとしてinfo
、error
同様warning
のRabbitMQへのメッセージここでは、懸念を見てください。Info
ログレベルをReceiveInfoLogsDirect.java
:
ReceiveInfoLogsDirect.java
public class ReceiveInfoLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws Exception {
String[] strs = new String[]{"info"};
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.20.128");
factory.setPort(5672);
factory.setUsername("carl");
factory.setPassword("198918");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
String queueName = channel.queueDeclare().getQueue();
for(String severity : strs){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
そして、ケアerror
とwarning
ログレベルReceiveWarningAndErrorLogsDirect.java
。
ReceiveWarningAndErrorLogsDirect.java
public class ReceiveWarningAndErrorLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws Exception {
String[] strs = new String[]{"error", "warning"};
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.20.128");
factory.setPort(5672);
factory.setUsername("carl");
factory.setPassword("198918");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
String queueName = channel.queueDeclare().getQueue();
for(String severity : strs){
channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
}
}
まずメインの方法で起動ReceiveInfoLogsDirect.java
し、ReceiveWarningAndErrorLogsDirect.java
メッセージを消費して、メッセージングプロバイダが起動EmitLogDirect.java
ログメッセージの異なるレベルを提供します。
ニュースプロバイダ
ログ・レベルのために送信されることがわかるwarning
、error
およびinfo
RabbitMQのメッセージ。
消費者のニュース - 情報
消費者は、その結合に内部のRabbitMQからのみ受信info
するメッセージのレベル
ニュース消費者 - 警告&エラー
消費者は、その結合にのみ内部のRabbitMQから受け取るwarning
とerror
、メッセージのレベル