RabbitMQ交换机(1)

1.交换机Exchange

RabbitMQ消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。

相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单,一方面它接收来自生产者的消息,另一方面将它们推入队列。交换机必须确切知道如何处理收到的消息。是应该把这些消息放到特定队列还是说把他们放到多个队列中还是说应该丢弃它们,这就的由交换机的类型来决定。

2.常见的交换机类型

  • 直接(direct)
  • 主题(topic)
  • 标题(headers)
  • 扇出(fanout)

3. 默认交换机(无名交换机)

java 复制代码
    channel.basicPublish("",QUEUE_NAME,null,message.getBytes());

上述代码中的第1个参数就是交换机名称,空字符串("")表示默认交换机(无名交换机)

3.绑定bindings

绑定bindings是交换机exchange与队列queue之间的桥梁

上图交换机X与队列Q1通过RoutingKey绑定,与队列Q2通过RoutingKey绑定

4.Fanout

Fanout扇出(广播/发布订阅),将接收到的所有消息广播到所有队列,类似于大喇叭,消息群发

一个消息生产者发消息给交换机,交换机通过相同的routingKey绑定2个队列,2个消费者收到同样的消息

4.1.消息生产者

java 复制代码
package com.hong.rabbitmq6;

import com.hong.utils.RabbitMQUtil;
import com.rabbitmq.client.Channel;

import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * @Description: 扇出模式消息发送者
 * @Author: hong
 * @Date: 2024-01-13 21:24
 * @Version: 1.0
 **/
public class EmitLog {
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入:");
        while (scanner.hasNext()){
            String message = scanner.next();
            channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes(StandardCharsets.UTF_8));
            System.out.println("消息发送完成------" + message);
        }
    }
}

4.2.消费者1

java 复制代码
package com.hong.rabbitmq6;

import com.hong.utils.RabbitMQUtil;
import com.hong.utils.SleepUtil;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

import java.nio.charset.StandardCharsets;

/**
 * @Description: 广播模式消息接收者1
 * @Author: hong
 * @Date: 2024-01-13 20:49
 * @Version: 1.0
 **/
public class Receive1 {
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        /*
         *声明交换机
         *第1个参数:交换机名称
         *第2个参数:交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
        //声明临时队列   当消费者断开与队列的连接,队列自动删除
        String queueName = channel.queueDeclare().getQueue();

        /*
         * 绑定队列与交换机
         * 第1个参数:队列名称
         * 第2个参数:交换机名称
         * 第3个参数:routingKey
         */
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        DeliverCallback deliverCallback = (comsumerTag, message) -> {
            System.out.println("Receive1接收到的消息:"+  new String(message.getBody(), StandardCharsets.UTF_8));
        };

        CancelCallback cancelCallback = var -> {
        };

        channel.basicConsume(queueName,true,deliverCallback,cancelCallback);
    }
}


4.3.消费者2

java 复制代码
package com.hong.rabbitmq6;

import com.hong.utils.RabbitMQUtil;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

import java.nio.charset.StandardCharsets;

/**
 * @Description: 广播模式消息接收者2
 * @Author: hong
 * @Date: 2024-01-13 20:49
 * @Version: 1.0
 **/
public class Receive2 {
    public static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
         /*
         *声明交换机
         *第1个参数:交换机名称
         *第2个参数:交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
        //声明临时队列   当消费者断开与队列的连接,队列自动删除
        String queueName = channel.queueDeclare().getQueue();

        /*
         * 绑定队列与交换机
         * 第1个参数:队列名称
         * 第2个参数:交换机名称
         * 第3个参数:routingKey
         */
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        DeliverCallback deliverCallback = (comsumerTag, message) -> {
            System.out.println("Receive2接收到的消息:"+  new String(message.getBody(), StandardCharsets.UTF_8));
        };

        CancelCallback cancelCallback = var -> {
        };

        channel.basicConsume(queueName,true,deliverCallback,cancelCallback);
    }
}



相关推荐
佛祖让我来巡山9 小时前
RabbitMQ 完整总结:架构、实战与可靠性保障
rabbitmq·消息队列可靠性
C***u17612 小时前
分布式多卡训练(DDP)踩坑
分布式
t***q3312 小时前
分布式监控Skywalking安装及使用教程(保姆级教程)
分布式·skywalking
CNRio12 小时前
人工智能基础架构与算力之2 异构算力合池技术:打破资源壁垒的分布式 AI 部署方案
人工智能·分布式
x***J34819 小时前
VueWebSocket案例
分布式·milvus·appcompat
2501_9418043220 小时前
Java在高并发互联网服务开发中的架构设计与性能优化实践全景分享
rabbitmq
努力发光的程序员1 天前
互联网大厂Java面试:从Spring Boot到微服务架构
spring boot·缓存·微服务·消息队列·rabbitmq·spring security·安全框架
20岁30年经验的码农1 天前
Kafka 消息中间件实战指南
分布式·kafka·linq
无心水1 天前
【分布式利器:限流】4、异步场景限流:消息队列削峰填谷+动态限流实现
分布式·mq·分布式限流·动态限流·分布式利器·异步场景限流·消息队列削峰填谷
2501_941147421 天前
基于 Kotlin 与 Ktor 构建高并发微服务与异步分布式系统实践分享
rabbitmq