javaはrabbitmqルーティングモデル(ルーティング/トピックキュー)、プロデューサーコンシューマーエクスチェンジメッセージキューを実装します

ファンアウトモデルでは、サブスクライブされたすべてのキューによってブレークが消費され、対応するエクスチェンジにバインドされたコンシューマーがメッセージを受信できます。ただし、シナリオによっては、さまざまなメッセージをさまざまなキューに送信し、さまざまなXiafeiで使用する必要があります。現時点では、ダイレクトタイプのスイッチを使用する必要があります。たとえば、ログは警告、情報、エラーなどの複数のタイプに分けられます。エラーログでは、エラータイプのログのみを表示する必要があります。すべてのログで、複数のタイプのログを記録する必要があります。

公式文書でわかるように、送信されたメッセージにバインディングキー、つまり秘密キーを与えます。キューがメッセージを受信すると、対応するバインディング確立と一致する必要があり、独自のルールを満たすメッセージは受け取られます。

ここに画像の説明を挿入

  1. プロデューサーは
    最初に、直接型スイッチを選択する必要があります。この時点で、私の/ 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. 消費者

消費者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. コンシューマー1とコンシューマー2をテスト開始してから、プロデューサーを開始し、情報タイプメッセージを送信します。

この時点で、
コンシューマー1と
ここに画像の説明を挿入
コンシューマー2が
ここに画像の説明を挿入表示され、コンシューマー1はメッセージを受信し、コンシューマー2は
メッセージを受信していません。別のエラーメッセージを送信します。

この時点で:
コンシューマー1
ここに画像の説明を挿入コンシューマー2
ここに画像の説明を挿入コンシューマー1と2の両方が、routingKey of errorのメッセージを受信したため、routingKeyに従ってどのメッセージをどのキューに送信するかを制御できます。

おすすめ

転載: blog.csdn.net/qq_41885819/article/details/112882630