RabbitMQ学习笔记

这篇博客详细介绍了RabbitMQ的基本概念,包括Message、Producer、Exchange、Binding、Queue、Connection和Consumer。解释了RabbitMQ的工作流程,以及如何使用SERVER常用指令。还提到了PHP访问RabbitMQ的场景和方法,提供了相关教程和文档链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RabbitMQ学习笔记

参考资料:
https://www.jianshu.com/p/79ca08116d57
https://blog.csdn.net/zhaozonglu/article/details/52370164

介绍
RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。
AMQP :Advanced Message Queue,高级消息队列协议。
它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

它具有以下特点:
1. 可靠性(Reliability)
    RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
2. 灵活的路由(Flexible Routing)
    在消息进入队列之前,通过 Exchange 来路由消息的。
    对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。
    针对更复杂的路由功能,可以将多个 Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。
3. 消息集群(Clustering)
    多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker 。
4. 高可用(Highly Available Queues)
    队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
5.多种协议(Multi-protocol)
    RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。
6. 多语言客户端(Many Clients)
    RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby、PHP 等等。
7. 管理界面(Management UI)
    RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。
8. 跟踪机制(Tracing)
    如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。
9. 插件机制(Plugin System)
    RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
名词定义

Message
消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由关键字)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

Routing Key:路由关键字,exchange根据这个关键字进行消息投递

producer
消息的生产者,也是一个向交换器发布消息的客户端应用程序。

Exchange
交换器,它指定消息按什么规则,路由到哪个队列。

Binding
绑定,它的作用就是把exchange和queue按照路由规则绑定起来
一个绑定就是基于路由关键字将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

Queue
消息队列,用来保存消息直到发送给消费者。
一个消息可投入一个或多个队列。
消息一直在队列里面,等待消费者连接到这个队列将其取走。

Connection
网络连接,比如一个TCP连接。

Channel
消息通道,多路复用连接中的一条独立的双向数据流通道,是建立在真实的TCP连接上的虚拟连接,AMQP 命令都是通过信道发出去的;
在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务

Consumer
消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

Virtual Host
虚拟主机,vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 /
一个broker里可以开设多个vhost,用作不同用户的权限分离

Broker
表示消息队列服务器实体。

工作流程
生产者(producer)产生的消息(Message)通过信道(channel)投递到某个交换器(exchange)上,
投递过程中指定了一个路由关键字(routing-key),交换器(exchange)将这条消息(Message)投递到不同的消息队列(Queue)中;
依据路由关键字(routing-key),该消息(Message)可能会被投递到某一个或者某几个符合路由规则的消息队列(Queue)中;
消费者(Consumer)从中取出消息(Message)进行后一步处理。

步骤:

发送方:
    获取 Conection;
    获取 Channel;
    定义 Exchange,Queue;
    使用一个RoutingKey将Queue Binding到一个Exchange上;
    通过指定一个Exchange和一个RoutingKey来将消息发送到对应的Queue上;
接收方在接收时:
    获取connection,接着获取channel;
    指定queue;
    然后到queue上取消息,它对Exchange,RoutingKey及如何binding都不关心;
说明

Exchange:

direct:完全匹配、单播的模式
消息中的 routing key 如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。
routing key 与队列名完全匹配,如果一个队列绑定到交换机要求routing key为“dog”,则只转发 routing key 标记为“dog”的消息,不会转发其他消息。

fanout:

每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。
fanout 交换器不处理路由关键字,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。
很像子网广播,每台子网内的主机都获得了一份复制的消息。
fanout 类型转发消息是最快的。

topic:

topic 交换器通过模式匹配分配消息的路由关键字属性,将路由关键字和某个模式进行匹配,此时队列需要绑定到一个模式上。
它将路由关键字和绑定键的字符串切分成单词,这些单词之间用点隔开。
它同样也会识别两个通配符:符号 # 和符号 *
# 匹配0个或多个单词,* 匹配一个单词
SERVER常用指令

rabbitmq的使用命令
rabbitmq-server start:启动rabbitmq服务

主要的管理rabbitmq使用的是rabbitctl命令

rabbitmqctl start_app 启动rabbitmq
rabbitmqctl stop_app 关闭rabbitmq
rabbitmqctl reset 重置rabbitmq队列
rabbitmqctl list_queues 查看rabbitmq中队列
rabbitmqctl list_exchanges 查看rabbitmq中的交换机
PHP访问

应用场景/使用方法:

官方demo:
https://github.com/rabbitmq/rabbitmq-tutorials/tree/master/php
https://github.com/php-amqplib/php-amqplib
官方文档翻译:
https://legacy.gitbook.com/book/xiaoxiami/rabbitmq_into_chinese_php/details
PHP:
https://blog.csdn.net/demon3182/article/category/7108232
其他:
https://blog.csdn.net/zyz511919766/article/details/41946521
https://www.cnblogs.com/luxiaoxun/p/3918054.html

PHP使用(php-amqplib 类库)
出处:https://www.cnblogs.com/oyxp/p/7376733.html

生产者:
1、创建连接

主要参数说明:
$host:  RabbitMQ服务器主机IP地址
$port:  RabbitMQ服务器端口
$user:  连接RabbitMQ服务器的用户名
$password:  连接RabbitMQ服务器的用户密码
$vhost:   连接RabbitMQ服务器的vhost(服务器可以有多个vhost,虚拟主机,类似nginx的vhost)

$connection =  new AMQPStreamConnection($host,$port,$user,$password,$vhost);

 
2、获取信道  
// $channel_id 信道id,不传则获取$channel[“”]信道,再无则循环$this->channle数组,下标从1到最大信道数找第一个不是AMQPChannel对象的下标,实例化并返回AMQPChannel对象,无则抛出异常No free channel ids

$channel = $connection->channel($channel_id);


3、在信道里创建交换器

 # $exhcange_name 交换器名字
 # $type 交换器类型:
’’  默认交换机 匿名交换器 未显示声明类型都是该类型
fanout  扇形交换器 会发送消息到它所知道的所有队列,每个消费者获取的消息都是一致的
headers 头部交换器
direct 直连交换器,该交换机将会对绑定键(binding key)和路由键(routing key)进行精确匹配
topic 话题交换器 该交换机会对路由键正则匹配,必须是*(一个单词)、#(多个单词,以.分割) 、      user.key .abc.* 类型的key

rpc 
#$passive  false
#durable false
#auto_detlete false 

$channel->exchange_declare($exhcange_name,$type,$passive,$durable,$auto_delete);
//常用设置 $passive=>false  $durable=>false $auto_delete->false


4、创建要发送的信息 ,可以创建多个消息
   #$data  string类型 要发送的消息
   #$properties array类型 设置的属性,比如设置该消息持久化[‘delivery_mode’=>2]

$msg = new AMQPMessage($data,$properties)

5、发送消息

#$msg object AMQPMessage对象
#$exchange string 交换机名字  
#$routing_key string 路由键 如果交换机类型
  fanout: 该值会被忽略,因为该类型的交换机会把所有它知道的队列发消息,无差别区别
direct  只有精确匹配该路由键的队列,才会发送消息到该队列
topic   只有正则匹配到的路由键的队列,才会发送到该队列
$channel->basic_publish($msg,$exchange,$routing_key);

6、关闭信道和链接

$channel->close();
$connection->close();


消费者:
1、创建连接

主要参数说明:
$host:  RabbitMQ服务器主机IP地址
$port:  RabbitMQ服务器端口
$user:  连接RabbitMQ服务器的用户名
$password:  连接RabbitMQ服务器的用户密码
$vhost:   连接RabbitMQ服务器的vhost(服务器可以有多个vhost,虚拟主机,类似nginx的vhost)

$connection =  new AMQPStreamConnection($host,$port,$user,$password,$vhost);


 
2、获取信道  
// $channel_id 信道id,不传则获取$channel[“”]信道,再无则循环$this->channle数组,下标从1到最大信道数找第一个不是AMQPChannel对象的下标,实例化并返回AMQPChannel对象,无则抛出异常No free channel ids

$channel = $connection->channel($channel_id);

3、在信道里创建交换器,未显式声明交换机都是使用匿名交换机

 # $exhcange_name 交换器名字
 # $type 交换器类型:
’’  默认交换机 匿名交换器 未显示声明类型都是该类型
fanout  扇形交换器 会发送消息到它所知道的所有队列,每个消费者获取的消息都是一致的
headers 头部交换器
direct 直连交换器,该交换机将会对绑定键(binding key)和路由键(routing key)进行精确匹配
topic 话题交换器 该交换机会对路由键正则匹配,必须是*(一个单词)、#(多个单词,以.分割) 、      user.key .abc.* 类型的key

rpc 
#$passive  false
#durable false
#auto_detlete false 

$channel->exchange_declare($exhcange_name,$type,$passive,$durable,$auto_delete);
//常用设置 $passive=>false  $durable=>false $auto_delete->false



4、声明消费者队列

(1)非持久化队列,RabbitMQ退出或者崩溃时,该队列就不存在

  list($queue_name, ,) = $channel->queue_declare("", false, false, false, false)
   
(2)持久化队列(需要显示声明,第三个参数要设置为true),保存到磁盘,但不一定完全保证不丢失信息,因为保存总是要有时间的。

 list($queue_name, ,) = $channel->queue_declare("ex_queue", false, false, true, false)



5、绑定交换机,当未显示绑定交换机时,默认是绑定匿名交换机

   #绑定:交换机与队列的关系,如下面这句代码意思是,$queue_name队列对logs交换机数据感兴趣,该队列就消费该交换机传过来的数据:这个队列(queue)对这个交换机(exchange)的消息感兴趣. $binding_key默认为空,表示对该交换机所有消息感兴趣,如果值不为空,则该队列只对该类型的消息感兴趣(除了fanout交换机以外)
   $channel->queue_bind($queue_name, 'logs', $binding_key);


6、消费消息

#该代码表示使用basic.qos方法,并设置prefetch_count=1。这样是告诉RabbitMQ,再同一时刻,不要发送超过1条消息给一个工作者(worker),直到它已经处理了上一条消息并且作出了响应。这样,RabbitMQ就会把消息分发给下一个空闲的工作者(worker),轮询、负载均衡配置

#$channel->basic_qos(null, 1, null);


#第四个参数 no_ack = false 时,表示进行ack应答,确保消息已经处理
#$callback 表示回调函数,传入消息参数
$channel->basic_consume('ex_queue', '', false, false, false, false, $callback);

$callback = function($msg){
  echo " [x] Received ", $msg->body, "\n";
  sleep(substr_count($msg->body, '.'));
  echo " [x] Done", "\n";

#当no_ack=false时, 需要写下行代码,否则可能出现内存不足情况#$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};

#监听消息,一有消息,立马就处理
while(count($channel->callbacks)) {
    $channel->wait();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值