ファンアウトモデルでは、サブスクライブされたすべてのキューによってブレークが消費され、対応するエクスチェンジにバインドされたコンシューマーがメッセージを受信できます。ただし、シナリオによっては、さまざまなメッセージをさまざまなキューに送信し、さまざまなXiafeiで使用する必要があります。現時点では、ダイレクトタイプのスイッチを使用する必要があります。たとえば、ログは警告、情報、エラーなどの複数のタイプに分けられます。エラーログでは、エラータイプのログのみを表示する必要があります。すべてのログで、複数のタイプのログを記録する必要があります。
公式文書でわかるように、送信されたメッセージにバインディングキー、つまり秘密キーを与えます。キューがメッセージを受信すると、対応するバインディング確立と一致する必要があり、独自のルールを満たすメッセージは受け取られます。
- プロデューサーは
最初に、直接型スイッチを選択する必要があります。この時点で、私の/ vh仮想ホストはデフォルトでamq.directという名前の直接型スイッチを提供します。amqp.directの直接型スイッチを再宣言することをお勧めします。これはエコーします。前の例のスイッチ。
public class Provider {
public void send() throws IOException, TimeoutException {
Connection connection = null;
Channel channel = null;
try {
connection = ConnectionUtils.getConnection();
// 获取连接通道
channel = connection.createChannel();
// 定义通道对应的交换机 参数一:交换机名称 参数二:类型 direct
channel.exchangeDeclare("amqp.direct","direct");
String routingKey = "info";
// 发送消息
channel.basicPublish("amqp.direct",routingKey,null,("direct message,routingKey为:" + routingKey + "," + System.currentTimeMillis()).getBytes());
}finally {
if (channel !=null && channel.isOpen()) {
channel.close();
}
if (connection != null && connection.isOpen()) {
connection.close();
}
}
}
public static void main(String[] args) throws IOException, TimeoutException {
Provider provider = new Provider();
provider.send();
}
}
プロデューサーを実行した後、元のスイッチリストのコードにスイッチがないため、rabbitmqは対応するスイッチを自動的に作成します。
- 消費者
消費者1:
public class Consumer01 {
public void consume() throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
// 获取连接通道
final Channel channel = connection.createChannel();
// 绑定交换机
channel.exchangeDeclare("amqp.direct","direct");
//创建临时队列
String queueName = channel.queueDeclare().getQueue();
// 绑定交换机和队列
channel.queueBind(queueName,"amqp.direct","info");
channel.queueBind(queueName,"amqp.direct","warn");
channel.queueBind(queueName,"amqp.direct","error");
// 每次只能消费一个消息
channel.basicQos(1);
// 消费消息
channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费消息:" + new String(body));
//参数一:确认队列中的那个消息 参数二:是否开启多个消息同时确认
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
public static void main(String[] args) throws IOException, TimeoutException {
Consumer01 consumer = new Consumer01();
consumer.consume();
}
}
消費者2:
public class Consumer02 {
public void consume() throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
// 获取连接通道
final Channel channel = connection.createChannel();
// 绑定交换机
channel.exchangeDeclare("amqp.direct","direct");
//创建临时队列
String queueName = channel.queueDeclare().getQueue();
// 绑定交换机和队列
channel.queueBind(queueName,"amqp.direct","error");
// 每次只能消费一个消息
channel.basicQos(1);
// 消费消息
channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费消息:" + new String(body));
//参数一:确认队列中的那个消息 参数二:是否开启多个消息同时确认
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
}
public static void main(String[] args) throws IOException, TimeoutException {
Consumer02 consumer = new Consumer02();
consumer.consume();
}
}
info、warn、およびerrorの3つのroutingKeyはコンシューマー1にバインドされ、errorのroutingKeyはコンシューマー2にバインドされます。
コンシューマー1とコンシューマー2をテスト開始してから、プロデューサーを開始し、情報タイプメッセージを送信します。
この時点で、
コンシューマー1と
コンシューマー2が
表示され、コンシューマー1はメッセージを受信し、コンシューマー2は
メッセージを受信していません。別のエラーメッセージを送信します。
この時点で:
コンシューマー1
コンシューマー2
コンシューマー1と2の両方が、routingKey of errorのメッセージを受信したため、routingKeyに従ってどのメッセージをどのキューに送信するかを制御できます。