2024年最全RabbitMQ实战学习(3),最新美团点评大数据开发团队面试题

本文详细介绍了RabbitMQ的Pub/Sub订阅模式、Routing路由模式和Topics通配符模式,包括各自的工作原理、代码实现及区别。同时,文章还提及了SpringBoot整合RabbitMQ的生产者和消费者实现,以及解决Erlang与RabbitMQ版本不匹配的问题。
摘要由CSDN通过智能技术生成

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

在这里插入图片描述

(4) 小结

  1. 在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。
  2. Work Queues 对于任务过重任务较多情况使用工作队列可以提高任务处理的速度。例如:短信服务部署多个,只需要有一个节点成功发送即可
1.3 Pub/Sub 订阅模式

(1)模式说明

在这里插入图片描述

在订阅模型中,多了一个 Exchange 角色,而且过程略有变化:

  • P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
  • C:消费者,消息的接收者,会一直等待消息到来
  • Queue:消息队列,接收消息、缓存消息
  • Exchange:交换机(X)。一方面,

接收生产者发送的消息

。另一方面,

知道如何处理消息

,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:

1. Fanout:**广播**,将消息交给**所有绑定到交换机的队列**
2. Direct:**定向**,把消息交给**符合指定routing key 的队列**
3. Topic:**通配符**,把消息交给**符合routing pattern(路由模式) 的队列**

Exchange(交换机)只负责转发消息不具备存储消息的能力,因此如果没有任何队列与 Exchange 绑定,或者没有符合路由规则的队列,那么消息会丢失!

(2)代码编写

生产者Producer_PubSub

package com.itheima.producer;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

//发布订阅模式
//发送消息
public class Producer\_PubSub {
    public static void main(String[] args) throws IOException, TimeoutException {
      //1.创建连接工厂
      ConnectionFactory factory=new ConnectionFactory();
      //2.设置参数
        factory.setHost("192.168.101.22");//ip地址 默认localhost
        factory.setPort(5672);//端口 默认值5672
        factory.setVirtualHost("/itcast");//虚拟机默认值 /虚拟机
        factory.setUsername("heima");//用户名 默认guest
        factory.setPassword("heima");//密码 默认guest
       //3.创建连接 connection
        Connection connection = factory.newConnection();
        //4.创建channel
        Channel channel = connection.createChannel();
        //5.创建交换机
        /\*
 exchangeDeclare
 (String exchange, 交换机名称
 BuiltinExchangeType type, 交换机类型 枚举类型
 DIRECT("direct"), :定向
 FANOUT("fanout"), :扇形(广播),发送消息到每一个与之绑定的队列
 TOPIC("topic"),:通配符方式
 HEADERS("headers");参数匹配
 boolean durable, 是否持久化
 boolean autoDelete, 是否自动删除
 boolean internal, 内部使用一般false
 Map<String, Object> arguments) 参数列表
 \*/
        String exchangeName="test\_fanout";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,true,false,false,null);
        //6.创建两个队列
        String queue1Name="test\_fanout\_queue1";
        String queue2Name="test\_fanout\_queue2";
        /\*
 String queue, boolean durable, boolean exclusive, boolean autoDelete,
 Map<String, Object> arguments)
 1.queue 队列名称
 2.durable 是否持久化,当mq重启之后,还在
 3.exclusive:
 \*是否独占:只能有一个消费者监听队列
 \*当connection关闭时,是否删除队列
 4.autoDelete: 是否自动删除,当没有consumer时,自动删除掉
 5.arguments: 参数
 \*/
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);
        //7,绑定队列和交换机
        /\*
 queueBind(String queue, String exchange, String routingKey)
 参数:
 1.queue: 队列名称
 2.exchange:交换机
 3.routingKey:路由键:绑定规则
 如果交换机的类型为fanout,routingKey设置为""
 \*/
        channel.queueBind(queue1Name,exchangeName,"");
        channel.queueBind(queue2Name,exchangeName,"");
        //8.发送消息
        String body="日志信息:张三调用了findAll方法...日志级别:info";
        channel.basicPublish(exchangeName,"",null,body.getBytes());
        //9.释放资源
        channel.close();
        connection.close();
    }
}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

Consumer_PubSub1

package com.itheima.consumer;
import com.rabbitmq.client.\*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer\_PubSub1 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //2.设置参数
        factory.setHost("192.168.101.22");//ip地址 默认localhost
        factory.setPort(5672);//端口 默认值5672
        factory.setVirtualHost("/itcast");//虚拟机默认值 /虚拟机
        factory.setUsername("heima");//用户名 默认guest
        factory.setPassword("heima");//密码 默认guest
        //3.创建连接 connection
        Connection connection = factory.newConnection();
        //4.创建channel
        Channel channel = connection.createChannel();
        //5.队列已经声明一次了,这里不用再声明队列
        String queue1Name="test\_fanout\_queue1";
        String queue2Name="test\_fanout\_queue2";
        //6.接收消息
        /\*
 basicConsume(String queue, boolean autoAck, Consumer callback)
 参数:
 1. queue:队列名称
 2. autoAck: 是否自动确认
 3. callback: 回调对象
 \*/
       Consumer consumer=new DefaultConsumer(channel){
           /\*
 回调方法,当收到消息后,会自动执行该方法
 1.consumerTag:标识
 2.envelope:获取一些信息。交换机,路由key...
 3.properties: 配置信息
 4.body: 数据
 \*/
           public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
              /\* System.out.println("consumerTag:"+consumerTag);
 System.out.println("exchange:"+envelope.getExchange());
 System.out.println("RoutingKey:"+envelope.getRoutingKey());
 System.out.println("properties:"+properties);\*/
               System.out.println("body:"+new String(body));//byte数组转string字符串
               System.out.println("将日志信息打印到控制台");
           }
       };
        channel.basicConsume(queue1Name,true,consumer);
        //关闭资源?不要,因为消费者要监听
    }
}


Consumer_PubSub2

package com.itheima.consumer;
import com.rabbitmq.client.\*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer\_PubSub2 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //2.设置参数
        factory.setHost("192.168.101.22");//ip地址 默认localhost
        factory.setPort(5672);//端口 默认值5672
        factory.setVirtualHost("/itcast");//虚拟机默认值 /虚拟机
        factory.setUsername("heima");//用户名 默
  • 30
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值