一文解析 RabbitMQ 最經常使用的三大模式

Direct 模式

  • 全部發送到 Direct Exchange 的消息被轉發到 RouteKey 中指定的 Queue。java

  • Direct 模式能夠使用 RabbitMQ 自帶的 Exchange: default Exchange,因此不須要將 Exchange 進行任何綁定(binding)操做。bash

  • 消息傳遞時,RouteKey 必須徹底匹配纔會被隊列接收,不然該消息會被拋棄,ide

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class DirectProducer {
    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");

        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_direct_exchange";
        String routingKey = "item.direct";

        //5. 發送
        String msg = "this is direct msg";
        channel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
        System.out.println("Send message : " + msg);

        //6. 關閉鏈接
        channel.close();
        connection.close();
    }
}
複製代碼
import com.rabbitmq.client.*;
import java.io.IOException;

public class DirectConsumer {

    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setAutomaticRecoveryEnabled(true);
        factory.setNetworkRecoveryInterval(3000);
      
        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_direct_exchange";
        String queueName = "test_direct_queue";
        String routingKey = "item.direct";
        channel.exchangeDeclare(exchangeName, "direct", true, false, null);
        channel.queueDeclare(queueName, false, false, false, null);

        //通常不用代碼綁定,在管理界面手動綁定
        channel.queueBind(queueName, exchangeName, routingKey);

        //5. 建立消費者並接收消息
        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 '" + message + "'");
            }
        };

        //6. 設置 Channel 消費者綁定隊列
        channel.basicConsume(queueName, true, consumer);

    }
}
複製代碼
Send message : this is direct msg
 
 [x] Received 'this is direct msg'
Topic 模式
複製代碼

Topic 模式

能夠使用通配符進行模糊匹配this

  • 符號'#" 匹配一個或多個詞spa

  • 符號"*」匹配很少很多一個詞code

例如:cdn

  • 'log.#"可以匹配到'log.info.oa"blog

  • "log.*"只會匹配到"log.erro「rabbitmq

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class TopicProducer {

    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");

        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_topic_exchange";
        String routingKey1 = "item.update";
        String routingKey2 = "item.delete";
        String routingKey3 = "user.add";

        //5. 發送
        String msg = "this is topic msg";
        channel.basicPublish(exchangeName, routingKey1, null, msg.getBytes());
        channel.basicPublish(exchangeName, routingKey2, null, msg.getBytes());
        channel.basicPublish(exchangeName, routingKey3, null, msg.getBytes());
        System.out.println("Send message : " + msg);

        //6. 關閉鏈接
        channel.close();
        connection.close();
    }
}
複製代碼
import com.rabbitmq.client.*;
import java.io.IOException;

public class TopicConsumer {

    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setAutomaticRecoveryEnabled(true);
        factory.setNetworkRecoveryInterval(3000);

        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_topic_exchange";
        String queueName = "test_topic_queue";
        String routingKey = "item.#";
        channel.exchangeDeclare(exchangeName, "topic", true, false, null);
        channel.queueDeclare(queueName, false, false, false, null);

        //通常不用代碼綁定,在管理界面手動綁定
        channel.queueBind(queueName, exchangeName, routingKey);

        //5. 建立消費者並接收消息
        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 '" + message + "'");
            }
        };
        //6. 設置 Channel 消費者綁定隊列
        channel.basicConsume(queueName, true, consumer);

    }
}
複製代碼
Send message : this is topc msg

[x] Received 'this is topc msg'
[x] Received 'this is topc msg'
複製代碼

Fanout 模式

不處理路由鍵,只須要簡單的將隊列綁定到交換機上發送到交換機的消息都會被轉發到與該交換機綁定的全部隊列上。 Fanout交換機轉發消息是最快的。隊列

import com.rabbitmq.client.*;
import java.io.IOException;

public class FanoutConsumer {
    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setAutomaticRecoveryEnabled(true);
        factory.setNetworkRecoveryInterval(3000);

        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_fanout_exchange";
        String queueName = "test_fanout_queue";
        String routingKey = "item.#";
        channel.exchangeDeclare(exchangeName, "fanout", true, false, null);
        channel.queueDeclare(queueName, false, false, false, null);

        //通常不用代碼綁定,在管理界面手動綁定
        channel.queueBind(queueName, exchangeName, routingKey);

        //5. 建立消費者並接收消息
        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 '" + message + "'");
            }
        };

        //6. 設置 Channel 消費者綁定隊列
        channel.basicConsume(queueName, true, consumer);
    }
}
複製代碼
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class FanoutProducer {

    public static void main(String[] args) throws Exception {
        //1. 建立一個 ConnectionFactory 並進行設置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        factory.setUsername("guest");
        factory.setPassword("guest");

        //2. 經過鏈接工廠來建立鏈接
        Connection connection = factory.newConnection();

        //3. 經過 Connection 來建立 Channel
        Channel channel = connection.createChannel();

        //4. 聲明
        String exchangeName = "test_fanout_exchange";
        String routingKey1 = "item.update";
        String routingKey2 = "";
        String routingKey3 = "ookjkjjkhjhk";//任意routingkey

        //5. 發送
        String msg = "this is fanout msg";
        channel.basicPublish(exchangeName, routingKey1, null, msg.getBytes());
        channel.basicPublish(exchangeName, routingKey2, null, msg.getBytes());
        channel.basicPublish(exchangeName, routingKey3, null, msg.getBytes());
        System.out.println("Send message : " + msg);

        //6. 關閉鏈接
        channel.close();
        connection.close();
    }
}
複製代碼
Send message : this is fanout msg

[x] Received 'this is fanout msg'
[x] Received 'this is fanout msg'
[x] Received 'this is fanout msg'
複製代碼
相關文章
相關標籤/搜索