【MQ】RabbitMQ 交换机案例代码

RabbitMQ Exchange类型:

  1. Direct交换机:完全按照Key进行投递
  2. Topic交换机:对Key进行模式匹配后进行投递: *匹配一个词,#匹配一个或多个词
  3. Fanout交换机:不需要key,通过广播模式,将消息投递到该交换机绑定的所有队列
  4. Headers交换机: 根据消息头部决定队列消息分发

1. Direct Exchange: 默认交换机

/**
 * Direct 交换机:完全按照RouteKey进行消息投递(默认交换机)
 * @author zhiwei_yang
 * @time 2020-8-4-9:45
 */
@Slf4j
public class DirectExchange {

    private final static String QUEUE_NAME = "DIRECT_EXCHANGE_QUEUE";
    private final static String ROUTE_KEY = QUEUE_NAME;
    private final static String EXCHANGE_NAME = "DirectExchange";

    public static void main(String[] argv) throws Exception {

        //创建连接内部的通道,用于发送和接收信息
        Channel channel = RabbitMqUtil.getChannel();

        //声明并创建DIRECT交换器:MsgExchange
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, false);

        //声明并创建消息队列:MsgQueue
        // durable: 是否持久化队列
        // exclusive: 排他队列:排他性队列,只对当前连接可见,链接断开自动删除
        // autoDelete: 队列不再使用会自动删除
        // arguments: 其他队列创建参数
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        //绑定交换器和消息队列
        // routing key:exchange将接收消息routing key="MsgQueue",转发到绑定的消息队列
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY);

        String message = "Hello Direct Exchange World!";
        channel.basicPublish(EXCHANGE_NAME, ROUTE_KEY, null, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");

        channel.close();
        channel.getConnection().close();
    }
}

2. Topic Exchange: 主题交换机,路由键模式匹配

/**
 * Topic 交换机: 按照Key匹配模式进行消息投递
 * @author zhiwei_yang
 * @time 2020-8-4-9:45
 */
@Slf4j
public class TopicExchange {

    private final static String QUEUE_NAME = "topic.exchange.queue";

    //*匹配一个词,#匹配一个或多个词, 自定义路由健单词用‘.’区分
    private final static String ROUTE_KEY_ONE = "topic.exchange.*";
    private final static String ROUTE_KEY_TWO = "topic.exchange.#";
    private final static String EXCHANGE_NAME = "TopicExchange";

    public static void main(String[] argv) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC, false);
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // Topic 交换机: 按照路由键模式匹配
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY_ONE);
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY_TWO);

        String message = "Single Word Match ===> Hello Topic Exchange World!";

        // 自定义路由键:topic.exchange.hello, 匹配Topic交换机路由键模式topic.exchange.*,会自动投递到指定主题:topic.exchange.queue
        channel.basicPublish(EXCHANGE_NAME, "topic.exchange.hello", null, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");

        // 多个单词模式匹配
        message = "Multi Word Match ===> Hello Topic Exchange World!";
        channel.basicPublish(EXCHANGE_NAME, "topic.exchange.hello.world", null, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");

        channel.close();
        channel.getConnection().close();
    }
}

3. Fanout Exchange: 类似消息广播分发,不区分路由键

/**
 * Fanout 交换机:无需Key直接投递到Fanout绑定的所有消息队列,类似广播模式
 * @author zhiwei_yang
 * @time 2020-8-4-9:45
 */
@Slf4j
public class FanoutExchange {

    private final static String QUEUE_NAME_ONE = "fanout.exchange.queue.one";
    private final static String QUEUE_NAME_TWO = "fanout.exchange.queue.two";
    private final static String EXCHANGE_NAME = "FanoutExchange";

    public static void main(String[] argv) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT, false);

        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);

        // Fanout 交换机,直接投递到所有绑定的消息队列
        channel.queueBind(QUEUE_NAME_ONE, EXCHANGE_NAME, "");
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "");

        String message = "Hello Fanout Exchange World!";

        //Fanout: 交换机无需路由键
        channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");

        channel.close();
        channel.getConnection().close();
    }
}

4. Headers Exchange: 根据消息头进行消息路由分发

/**
 * Headers 交换机:根据头部数据决定消息路由分发
 * @author zhiwei_yang
 * @time 2020-8-4-9:45
 */
@Slf4j
public class HeadersExchange {

    private final static String QUEUE_NAME_ONE = "headers.exchange.queue.one";
    private final static String QUEUE_NAME_TWO = "headers.exchange.queue.two";
    private final static String EXCHANGE_NAME = "HeadersExchange";

    public static void main(String[] argv) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.HEADERS, false);
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);

        Map<String,Object> headerOne = new HashMap<>(1);
        headerOne.put("topic-one", "email");
        channel.queueBind(QUEUE_NAME_ONE, EXCHANGE_NAME, "", headerOne);

        Map<String,Object> headerTwo = new HashMap<>(1);
        headerTwo.put("topic-two", "message");
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "", headerTwo);

        String message = "Hello Headers Exchange World!";

        // 消息队列headers.exchange.queue.one 投递
        AMQP.BasicProperties propertiesOne = new AMQP.BasicProperties.Builder().headers(headerOne).build();
        channel.basicPublish(EXCHANGE_NAME, "", propertiesOne, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");

        // 消息队列headers.exchange.queue.two 投递
        AMQP.BasicProperties propertiesTwo = new AMQP.BasicProperties.Builder().headers(headerTwo).build();
        channel.basicPublish(EXCHANGE_NAME, "", propertiesTwo, message.getBytes(StandardCharsets.UTF_8));
        log.info(" [x] Sent '" + message + "'");
        channel.getConnection().close();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章