本文仅为个人理解,如有错误请指正,会有另一篇文章作为C# 使用RabbitMQ文章,包含各种五种RabbitMQ工作模式Demo。
- RabbitMQ简介
RabbitMQ是实现了高级消息队列协议(AMQP)的开源代理软件(也称为面向消息的中间件),RabbitMQ服务器是用Erlang语言编写,所有主要的编程语言均有与代理接口通信的客户端库。
- AMQP协议
Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品、不同的开发语言等条件的限制。
- Erlang语言
是一种通用面向并发的编程语言,由爱立信所辖的CS-Lab开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。
-
Rabbit优点
-
RabbitMQ使用AMQP协议。
-
可靠性,RabbitMQ支持持久化,保证了信息的稳定性。
-
高并发,使用Erlang开发语言。
-
集群部署简单。
- RabbitMQ传递模型
RabbitMQ消息传递模型的核心思想是生产者(Producer)永远不会将任何消息直接发送到队列(Queue),实际上生产者不需要知道消息是否被传递到任何队列,生产者只能向交换机(Exchange)发送消息,交换机的工作是一边接收来自生产者的消息,另一边讲消息推送到队列。
- 概念:
Broker:代理,也就是RabbitMQ本身,接受和转发消息,维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输。
Producer:消息的创建者,负责创建和推送数据到消息服务器。
Queue:队列,本质上是一个大的消息缓冲器,生产者可以将消息发送到一个队列,而消费者可以尝试从一个队列接受输入。
Consumer:消息的消费者,等待接收信息,处理数据和确认消息。
Exchange:交换机,负责接收消息和将消息推送到队列,具有四中模式。
Routing Key:路由键,交换机根据路由键确定将消息推送到正确的队列。
Binding:绑定,交换机和队列的之间的关系,用于把交换器的消息绑定到队列上,绑定需要依赖路由键。
Vhost:虚拟主机,一个代理中可以有多个虚拟主机,每个虚拟主机都是一个Mini的RabbitMQ,拥有自己的队列、交换机、绑定、权限,RabbitMQ默认的vhost是‘/’。vhost之间相互隔离,所以不需要担心命名冲突问题。
Channel:消息通道,在客户端的每个连接里可以建立多个通道,依赖于AMQP。
-
交换机四中模式:
-
direct:直接模式,处理路由键,需要将一个队列绑定到交换机上,要求消息与一个特定的路由键完全匹配,才会将该信息转发到指定的队列。
-
fanout:扇出模式,不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
-
topic:主题模式,也称匹配模式处理路由键,不能使用任意的路由键,路由键必须满足由点分割的单词列表,单词可以是任意内容。使用特定路由密钥发送的消息将被传递到与匹配的绑定密钥绑定的所有队列,绑定键有两个重要的特殊情况,用*(星号)替代一个单词,用#(hash)可以替换零个或多个单词。
-
headers:标题模式,不处理路由键。而是根据发送的消息内容中的headers属性进行匹配。在绑定Queue与Exchange时指定一组键值对;当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers属性是一个键值对,可以是Hashtable,键值对的值可以是任何类型。而fanout,direct,topic 的路由键都需要要字符串形式的。
-
消息确认:
RabbitMQ支持消息确认,消费者发回ask告诉RabbitMQ已收到消息,RabbitMQ才会自由删除消息。
Rabbit支持两种确认方式:手动消息确认和自动消息确认,建议使用手动确认消息方式,防止由于通道关闭、连接关闭或TCP连接丢失情况而导致消息未处理完成而删除情况。
Rabbit默认开始自动确认消息模式,如果未进行消息确认,RabbitMQ将会占用越来越多的内容,消息会一直存在于队列里。
- 持久化
消息确认会保证即使消费者死亡,消息不会丢失,但是当RabbitMQ服务器停止后,队列和消息依然会丢失。
确保消息持久化需要进行两步设置:队列持久化和消息持久化。
交换机也支持持久化,如果RabbitMQ工作模式需要声明交换机,建议设置交换机的持久化状态和队列、消息持久化状态一致。
- 安装
- 下载地址:http://www.rabbitmq.com/download.html,RabbitMQ运行依赖于Erlang,下载安装会提示进行下载Erlang。
- 安装完成后->开始->RabbitMQ Command Prompt
- 安装RabbitMQ服务:rabbitmq-plugins enable rabbitmq_management
- 启动/停止服务:net stop/start rabbitmq
- 地址:http://127.0.0.1:15672/
- 账号、密码:guest/guest
- guest默认只能本地访问,修改安装目录下ebin/rabbit.app文件将loopback_users键中值<<"guest">>删除,重启服务即可。
- 用户角色:
新增用户,默认没有任何角色,通常作为生产者和消费者。
- administrator:超级管理员,可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。
- monitoring:监控者,可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
- policymaker:策略制定者,可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
- management:普通管理者,仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。
- 用户权限:
用户权限指的是用户对exchange,queue的操作权限,包括配置权限,读写权限。配置权限会影响到exchange,queue的声明和删除。读写权限影响到从queue里取消息,向exchange发送消息以及queue和exchange的绑定(bind)操作。
设置用户权限,需要指定vhost,如果不指定则是默认的vhost'/'。
- 常用命令
- 增加用户:rabbitmqctl add_user [userName] [password]
- 删除用户:rabbitmqctl delete_user [userName]
- 修改密码:rabbitmqctl change_password [userName] [newPassword]
- 设置用户角色:rabbitmqctl set_user_tags [userName] [tag1,tag2...]
- 显示所有用户:rabbitmqctl list_users
- 设置用户权限:rabbitmqctl set_permissions -p [vhostPath] [userName] [conf] [write] [read] conf、write、read:均表示一个正则表达式,分别匹配特定则资源
- 显示用户权限:rabbitmqctl list_user_permissions [userName]
- 清除用户权限:rabbitmqctl clear_permissions [-p vhostpath] [userName]
- 显示虚拟主机下的所有用户权限:rabbitmqctl list_permissions [-p vhostPath]
- 创建虚拟主机:rabbitmqctl add_vhost [vhostPath]
- 删除虚拟主机:rabbitmqctl delete_vhost [vhostPath]
- 显示所有虚拟主机:rabbitmqctl list_vhosts
- 查看队列:rabbitmqctl list_queues [-p vhostPath]
- 删除指定的队列:rabbitmqctl delete_queue [-p vhostPath] [queueName]
- 显示绑定:rabbitmqctl list_bindings [-p vhostPath]
- 显示交换机:rabbitmqctl list_exchanges [-p vhostPath]
- 显示RabbitMQ节点状态:rabbitmqctl status
- 启动rabbitMQ应用:rabbitmqctl start_app
- 停止rabbitMQ应用:rabbitmqctl stop_app
- 重置节点:rabbitmqctl reset、rabbitmqctl force_reset force_reste与reset的区别是无条件重置节点,不管当前管理数据库状态以及集群配置。只有停止rabbitmq应用后,执行reset和force_reset才能成功