RabbitMQ中的基本概念
Contents
RabbitMQ的工作流程
----------------------- virtual host ------------------------------
| -> queue |
|publisher -> exchange -> [binding] -> queue -> consumer |
| -> queue |
----------------------- virtual host ------------------------------
RabbitMQ是通过virtual host
的概念来实行环境隔离的.
以下,来理解下各个概念
Virtual Host
为了在一个单独的代理上实现多个隔离的环境(用户、用户组、交换机、队列 等),AMQP提供了一个虚拟主机(virtual hosts - vhosts)的概念
默认的virtual host
为/
.
创建一个virtual host
rabbitmqctl add_vhost test
例如:
➜ ~ rabbitmqctl add_vhost test
Creating vhost "test" ...
➜ ~
删除一个virtual host
rabbitmqctl delete_vhost test
例如:
➜ ~ rabbitmqctl delete_vhost test
Deleting vhost "test" ...
➜ ~
列出所有virtual host
rabbitmqctl list_vhosts name tracing
例如:
➜ ~ rabbitmqctl list_vhosts
Listing vhosts ...
/
test
➜ ~
➜ ~ rabbitmqctl list_vhosts name tracing
Listing vhosts ...
/ false
test false
➜ ~
exchange (交换机)
交换机是用来发送消息的AMQP实体。交换机拿到一个消息之后将它路由给一个或零个队列。它使用哪种路由算法是由交换机类型和被称作绑定(bindings)的规则所决定的
default exchange (默认交换机)
默认交换机(default exchange)实际上是一个由消息代理预先声明好的没有名字(名字为空字符串)的*直连交换机(direct exchange)*。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同。
Direct exchange(直连交换机)
直连型交换机(direct exchange)是根据消息携带的路由键(routing key)将消息投递给对应队列的。直连交换机用来处理消息的单播路由(unicast routing)(尽管它也可以处理多播路由)
注意,这个路由键必须完全匹配才能投递.
funout exchange (扇形交换机)
扇型交换机(funout exchange)将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键。如果N个队列绑定到某个扇型交换机上,当有消息发送给此扇型交换机时,交换机会将消息的拷贝分别发送给这所有的N个队列。扇型用来交换机处理消息的广播路由(broadcast routing)。
topic exchanges (主题交换机)
主题交换机(topic exchanges)通过对消息的路由键和队列到交换机的绑定模式之间的匹配,将消息路由给一个或多个队列。主题交换机经常用来实现各种分发/订阅模式及其变种。主题交换机通常用来实现消息的多播路由(multicast routing)。
headers exchange (头交换机)
头交换机使用多个消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则.
头交换机可以视为直连交换机的另一种表现形式。头交换机能够像直连交换机一样工作,不同之处在于头交换机的路由规则是建立在头属性值之上,而不是路由键。路由键必须是一个字符串,而头属性值则没有这个约束,它们甚至可以是整数或者哈希值(字典)等
交换机常用属性
- Name: 交换机名
- Durability: (消息代理重启后,交换机是否还存在)
- Auto-delete: (当所有与之绑定的消息队列都完成了对此交换机的使用后,删掉它)
- Arguments:(依赖代理本身)
常用命令
列出所有交换机
rabbitmqadmin -V test list exchanges
例如:
➜ ~ rabbitmqadmin -V / list exchanges
+--------------------+---------+
| name | type |
+--------------------+---------+
| | direct |
| amq.direct | direct |
| amq.fanout | fanout |
| amq.headers | headers |
| amq.match | headers |
| amq.rabbitmq.log | topic |
| amq.rabbitmq.trace | topic |
| amq.topic | topic |
+--------------------+---------+
➜ ~
声明一个交换机
rabbitmqadmin declare exchange name=my-new-exchange type=fanout
type可以参考上面的类型.
queue (队列)
队列在声明(declare)后才能被使用。如果一个队列尚不存在,声明一个队列会创建它。如果声明的队列已经存在,并且属性完全相同,那么此次声明不会对原有队列产生任何影响。如果声明中的属性与已存在队列的属性有差异,那么一个错误代码为406的通道级异常就会被抛出
常用属性
- Name: 队列名
- Durable:(消息代理重启后,队列依旧存在)
- Exclusive:(只被一个连接(connection)使用,而且当连接关闭后队列即被删除)
- Auto-delete:(当最后一个消费者退订后即被删除)
- Arguments:(一些消息代理用他来完成类似与TTL的某些额外功能)
常用命令
列出队列简要信息
rabbitmqadmin list queues vhost name node messages message_stats.publish_details.rate
例如:
➜ ~ rabbitmqadmin list queues vhost name node messages message_stats.publish_details.rate
+-------+-------------+------------------+----------+------------------------------------+
| vhost | name | node | messages | message_stats.publish_details.rate |
+-------+-------------+------------------+----------+------------------------------------+
| / | yangzhiyong | rabbit@localhost | 0 | |
+-------+-------------+------------------+----------+------------------------------------+
➜ ~
列出队列尽可能详细信息
rabbitmqadmin -f long -d 3 list queues
声明一个队列
rabbitmqadmin declare queue name=my-new-queue durable=false
发布一条消息
rabbitmqadmin publish exchange=amq.default routing_key=test payload="hello, world"
取出一条消息
rabbitmqadmin get queue=test requeue=false
Binding (绑定)
绑定(Binding)是交换机(exchange)将消息(message)路由给队列(queue)所需遵循的规则.
示例
扇形交换机使用例子
声明一个扇形交换机:
➜ ~ rabbitmqadmin declare exchange name=myexchange type=fanout
exchange declared
声明两个队列
➜ ~ rabbitmqadmin declare queue name=myqueue durable=true
queue declared
➜ ~ rabbitmqadmin declare queue name=myqueue2 durable=true
queue declared
➜ ~
绑定队列到交换机
➜ ~ rabbitmqadmin declare binding source=myexchange destination_type="queue" destination="myqueue" routing_key="ignore_routing_key"
binding declared
➜ ~
➜ ~ rabbitmqadmin declare binding source=myexchange destination_type="queue" destination="myqueue2" routing_key="ignore_routing_key"
binding declared
➜ ~
发布一条消息到交换myexchange
➜ ~ rabbitmqadmin publish exchange=myexchange routing_key="ignore_routing_key" payload="hello, world, from publisher"
Message published
➜ ~
从队列"myqueue"出队一条消息
➜ ~ rabbitmqadmin get queue=myqueue requeue=true
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
| routing_key | exchange | message_count | payload | payload_bytes | payload_encoding | properties | redelivered |
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
| ignore_routing_key | myexchange | 0 | hello, world, from publisher | 28 | string | | False |
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
➜
从队列"myqueue2"出队一条消息
➜ ~ rabbitmqadmin get queue=myqueue2 requeue=true
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
| routing_key | exchange | message_count | payload | payload_bytes | payload_encoding | properties | redelivered |
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
| ignore_routing_key | myexchange | 0 | hello, world, from publisher | 28 | string | | False |
+--------------------+------------+---------------+------------------------------+---------------+------------------+------------+-------------+
➜
注意,扇形交换机会忽略routing_key的,只要队列绑定到了扇形交换机,那么扇形交换机就会将这些消息,都会发给每一个队列.
其他有兴趣的, 可以自行测试.
还有, 这里没有指明virtual host
,那么就是默认的/
.如果指定了virtual host,那么上面的每条命令的virtual host
都要相同.