一、消息队列简介
1. 主流的消息队列
-
ActiveMQ
- 简介:Apache ActiveMQ 是一个功能丰富的、完全支持 Java Message Service (JMS) 1.1 和 2.0 规范的消息中间件。它提供了多种消息传递模型,如点对点 (P2P) 和发布/订阅 (Pub/Sub),并且支持多种传输协议,比如 AMQP、STOMP、MQTT 等。
- 特点:高度可扩展,易于集成,支持多种编程语言和协议。
- 应用场景:适用于需要支持多种协议和语言的企业级应用。
-
RocketMQ
- 简介:RocketMQ 是阿里巴巴开源的消息中间件,现已成为 Apache 顶级项目。它是一个分布式的、高吞吐量、低延迟的消息队列系统,支持消息的顺序消费、消息过滤等功能。
- 特点:高性能、高可靠、支持消息轨迹查询。
- 应用场景:适用于电商、金融等领域需要高可用性和高性能消息传递的场景。
-
Kafka
- 简介:Apache Kafka 是一个分布式的流处理平台,最初由 LinkedIn 开发,后来成为 Apache 项目。Kafka 以其高吞吐量、低延迟和持久性而闻名。
- 特点:能够处理大量实时数据流,支持水平扩展。
- 应用场景:适用于大数据、流处理、日志聚合等场景。
-
RabbitMQ
- 简介:RabbitMQ 是一个开源的消息代理软件,基于 AMQP 协议,支持多种消息传递模式,如点对点和发布/订阅。
- 特点:支持多种客户端语言,易于使用,具有良好的社区支持。
- 应用场景:适用于微服务架构中的消息传递、任务调度等场景。
-
ZeroMQ
- 简介:ZeroMQ 是一个轻量级的消息队列库,不是传统的消息中间件,而是一个库,可以嵌入到应用程序中。
- 特点:灵活,支持多种消息传递模式,如 PUB/SUB、REQ/REP、DEALER/ROUTER 等。
- 应用场景:适用于需要快速开发和部署的应用程序,特别是对于那些需要高性能和低延迟的场景。
2.各种不同消息队列的对比
-
ActiveMQ
- 特性 :
- 支持多种消息传递模式(P2P, Pub/Sub)。
- 支持多种传输协议(AMQP, MQTT, STOMP, OpenWire, WebSocket等)。
- 提供持久化选项。
- 高度可扩展。
- 优点 :
- 成熟稳定,社区支持良好。
- 易于集成。
- 缺点 :
- 性能相对较低。
- 配置较为复杂。
- 特性 :
-
RocketMQ
- 特性 :
- 高性能,支持高吞吐量和低延迟。
- 支持消息轨迹查询和消息过滤。
- 分布式设计,支持水平扩展。
- 优点 :
- 极高的可靠性和稳定性。
- 强大的消息处理能力。
- 缺点 :
- 学习曲线较陡峭。
- 社区相对较小。
- 特性 :
-
Kafka
- 特性 :
- 高吞吐量,低延迟。
- 支持数据持久化。
- 支持水平扩展。
- 支持消息重播。
- 优点 :
- 极佳的性能和扩展性。
- 强大的数据流处理能力。
- 缺点 :
- 对硬件要求较高。
- 学习成本较高。
- 特性 :
-
RabbitMQ
- 特性 :
- 支持多种消息传递模式(P2P, Pub/Sub)。
- 支持多种客户端语言。
- 支持消息确认机制。
- 优点 :
- 使用简单,易于集成。
- 社区活跃,文档丰富。
- 缺点 :
- 相对而言性能较低。
- 不支持大规模集群部署。
- 特性 :
-
ZeroMQ
- 特性 :
- 轻量级库,可直接嵌入到应用程序中。
- 支持多种消息传递模式(PUB/SUB, REQ/REP, DEALER/ROUTER等)。
- 高性能。
- 优点 :
- 快速开发和部署。
- 低延迟。
- 缺点 :
- 缺乏传统消息中间件的功能(如持久化)。
- 较难维护和管理。
- 特性 :
3.消息队列中的角色/名词解释
-
Broker:
- 定义: 消息中间件服务,负责接收来自生产者的消息,并将它们分发给消费者。
- 作用: 管理消息队列和交换器,实现消息的存储和转发。
-
Producer:
- 定义: 发送消息到消息队列的一方。
- 作用: 创建消息并将消息发送给Broker。
-
Consumer:
- 定义: 接收消息的一方。
- 作用: 从Broker中获取消息并进行处理。
-
Topic:
- 定义: 在发布/订阅模型中,消息被发送到特定的主题。
- 作用: 作为消息分类的标签,多个消费者可以订阅同一主题。
-
Queue:
- 定义: 存储消息的数据结构。
- 作用: 在点对点模型中,用于存储等待被消费的消息。
-
Message:
- 定义: 被传递的数据单元。
- 作用: 包含了实际要传递的信息。
3.消息队列中的两种工作模式
(1). Point-to-Point (P2P)
-
定义:
- 在点对点模式中,消息被发送到一个队列,然后由一个消费者接收。一旦消息被接收,它就会从队列中移除。
-
用法:
- 生产者: 发送消息到队列。
- 消费者: 从队列中接收消息。一个消息只被一个消费者接收。
-
特点:
- 一对一: 每个消息只有一个消费者。
- 消息确认: 消费者通常需要确认消息已经被成功处理。
- 消息持久化: 可以设置消息是否需要持久化。
-
应用场景:
- 适用于消息需要被处理一次且仅一次的情况。
- 例如,订单处理、文件上传等任务。
(2). Publish/Subscribe (Pub/Sub)
-
定义:
- 在发布/订阅模式中,消息被发布到一个主题,然后由所有订阅该主题的消费者接收。
-
用法:
- 发布者: 发布消息到主题。
- 订阅者: 订阅特定主题,并接收所有发布到该主题的消息。
-
特点:
- 一对多: 一个消息可以被多个消费者接收。
- 消息过滤: 消费者可以根据需要订阅特定的消息。
- 消息持久化: 通常不需要消息持久化,因为消息会被立即广播给所有订阅者。
-
应用场景:
- 适用于消息需要被多个消费者同时接收的情况。
- 例如,实时新闻更新、市场数据推送等。
5.消息队列的缺点
(1). 系统可用性降低:
引入了额外的服务层,如果消息队列服务出现故障,可能会导致整个系统的不可用。
(2). 系统复杂性提高:
需要维护额外的中间件服务,增加了系统的复杂性和维护成本。
可能需要考虑如何优雅地处理消息队列服务的故障恢复。
(3). 数据一致性无法保证:
由于消息传递是异步的,可能会导致数据的一致性问题。
需要设计额外的机制来确保数据的一致性,例如使用事务性消息或补偿机制。
二:RabbitMQ介绍
1:RabbitMQ相关术语
1. 生产者 (Producer)
- 定义:生产者是向 RabbitMQ 发送消息的应用程序或服务。
- 功能:生产者通常不会直接将消息发送到队列中,而是将消息发送到交换器,由交换器根据规则来决定消息如何被路由到合适的队列。
2. 消费者 (Consumer)
- 定义:消费者是从 RabbitMQ 接收消息的应用程序或服务。
- 功能:消费者通过监听特定的队列来接收消息。当队列中有新消息到达时,消费者会被通知并处理这些消息。
3. 队列 (Queue)
- 定义:队列是 RabbitMQ 中用来保存消息的数据结构。
- 功能:队列遵循先进先出 (FIFO) 的原则,但也可以配置成其他形式。队列可以设置为持久化,这样即使 RabbitMQ 重启后,队列中的消息也不会丢失。
4. 交换器 (Exchange)
- 定义:交换器是一种接收来自生产者的消息,并将它们路由到队列的组件。
- 功能 :交换器可以基于不同的策略来路由消息,如直接匹配 (
direct
)、主题匹配 (topic
)、头信息匹配 (headers
) 或者简单的广播 (fanout
)。这种灵活性使得消息可以根据复杂的规则进行分发。
5. 虚拟主机 (Virtual Host)
- 定义:虚拟主机是 RabbitMQ 中的一个逻辑分组单元,它像是一个独立的 RabbitMQ 实例。
- 功能:每个虚拟主机都有自己的队列、交换器和绑定关系。使用虚拟主机可以在单个 RabbitMQ 服务器上模拟多个独立的实例,从而实现资源隔离和权限管理。
三:CentOS7下安装RabbitMQ(单机)
1:安装erlang
RabbitMQ 基于 Erlang 编程语言编写,因此首先需要安装 Erlang。
1.1 更新系统包
sudo yum update -y
1.2 添加 Erlang Solutions 的官方仓库
sudo rpm -Uvh https://packages.erlang-solutions.com/erlang-solutions-1.0-1.el7.noarch.rpm
1.3 安装 Erlang
sudo yum install esl-erlang -y
2:安装RabbitMQ
2.1 添加 RabbitMQ 的官方仓库
sudo yum install epel-release
sudo yum install rabbitmq-server
3:启动RabbitMQ
3.1 启动服务
sudo systemctl start rabbitmq-server
3.2 设置开机启动
sudo systemctl enable rabbitmq-server
4:开启web管理控制台
4.1 安装管理插件
sudo rabbitmq-plugins enable rabbitmq_management
4.2 访问管理界面
打开浏览器访问 http://localhost:15672
。默认用户名和密码都是 guest
。
5:Nginx代理
为了能够从外部网络访问 RabbitMQ 的管理控制台,可以通过 Nginx 进行反向代理。
5.1 安装 Nginx
sudo yum install nginx
5.2 配置 Nginx
编辑 /etc/nginx/conf.d/rabbitmq.conf
文件,添加以下内容:
server {
listen 80;
server_name rabbit.example.com; # 替换为你的域名
location / {
proxy_pass http://localhost:15672/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
5.3 测试并重启 Nginx
sudo nginx -t
sudo systemctl restart nginx
附加步骤:设置防火墙
确保防火墙允许必要的端口。例如,对于 RabbitMQ 的管理界面,需要开放 TCP 端口 15672。
sudo firewall-cmd --permanent --add-port=15672/tcp
sudo firewall-cmd --reload
现在你应该可以通过 http://rabbit.example.com
访问到 RabbitMQ 的管理控制台了。请注意,这里的 rabbit.example.com
应该替换为你实际使用的域名,并确保 DNS 已经正确解析。
四:rabbitmq常用命令
RabbitMQ 提供了一系列的命令行工具来管理和监控服务器。这些工具通常位于 /usr/lib/rabbitmq/bin/
目录下。下面是关于您提到的一些常见命令的概述:
1:虚拟机管理
虚拟主机是 RabbitMQ 中的逻辑分组单元,类似于独立的 RabbitMQ 实例。
创建虚拟主机
rabbitmqctl add_vhost <vhost>
列出所有虚拟主机
rabbitmqctl list_vhosts
删除虚拟主机
rabbitmqctl delete_vhost <vhost>
2:用户管理
用于管理 RabbitMQ 用户账户。
创建用户
rabbitmqctl add_user <username> <password>
设置用户标签
rabbitmqctl set_user_tags <username> <tag1> <tag2> ...
列出所有用户
rabbitmqctl list_users
删除用户
rabbitmqctl delete_user <username>
3:tags角色介绍
(1) 超级管理员 (administrator): guest
- 描述: 具有对所有虚拟主机的完全访问权限。
- 示例 :
rabbitmqctl set_user_tags guest administrator
(2) 监控者 (monitoring)
- 描述: 可以查看节点状态和监控消息队列。
- 示例 :
rabbitmqctl set_user_tags user monitoring
(3) 策略制定者 (policymaker)
- 描述: 可以设置和管理策略。
- 示例 :
rabbitmqctl set_user_tags user policymaker
(4) 普通管理者 (management)
- 描述: 可以查看管理界面,但不能更改配置。
- 示例 :
rabbitmqctl set_user_tags user management
(5) 其他
- 描述: 具有有限的权限,通常只能与特定虚拟主机交互。
- 示例 :
rabbitmqctl set_user_tags user
4:插件管理
用于管理 RabbitMQ 的插件。
启用插
rabbitmq-plugins enable <plugin_name>
禁用插件
rabbitmq-plugins disable <plugin_name>
列出已启用插件
rabbitmq-plugins list
5:限制
用于设置连接和队列的限制。
设置连接限制
rabbitmqctl set_connection_limit <vhost> <limit>
设置队列长度限制
rabbitmqctl set_queue_length <vhost> <queue> <limit>
6:其他
清空队列
rabbitmqctl purge_queue <vhost> <queue>
关闭连接
rabbitmqctl close_connection <connection_name>
关闭通道
rabbitmqctl close_channel <channel_name>
设置消息 TTL
rabbitmqctl set_policy <policy_name> <vhost> <queue> '{"message-ttl": <ttl>}' --priority <priority>
清除所有消息
rabbitmqctl reset
获取节点状态
rabbitmqctl status
停止所有服务
rabbitmqctl stop_app
启动所有服务
rabbitmqctl start_app
列出所有队列
rabbitmqctl list_queues
列出所有绑定
rabbitmqctl list_bindings
五:RabbitMQ集群
1:元数据
在 RabbitMQ 集群中,元数据(例如队列、交换器、绑定等)在集群中的所有节点上都是一致的。这意味着如果在一个节点上创建了一个队列,那么这个队列会在所有的节点上可见。
2:内存节点与磁盘节点
- 内存节点:这些节点主要使用内存来存储队列数据,适用于高吞吐量的应用场景。
- 磁盘节点:这些节点将队列数据存储在磁盘上,适用于需要数据持久性的应用场景。
3:规划
在开始部署之前,需要规划好集群的拓扑结构,包括节点的数量、角色分配、网络配置等。
4:部署集群
(1)配置hosts以及hostname
确保每台机器的 hostname 和 hosts 文件都正确配置,以便各节点之间能够互相识别。
在每台机器上修改 /etc/hostname
sudo hostnamectl set-hostname <hostname>
修改 /etc/hosts
文件
sudo nano /etc/hosts
在 hosts 文件中添加集群中所有节点的 IP 地址和对应的 hostname,例如:
192.168.1.101 node1
192.168.1.102 node2
192.168.1.103 node3
(2)关闭selinux以及firewalld
确保 SELinux 和 Firewall 不会干扰 RabbitMQ 的通信。
关闭 SELinux
sudo setenforce 0
sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
关闭 Firewall
sudo systemctl stop firewalld
sudo systemctl disable firewalld
(3)安装rabbitmq
在每台机器上安装 Erlang 和 RabbitMQ。
安装 Erlang
sudo rpm -Uvh https://packages.erlang-solutions.com/erlang-solutions-1.0-1.el7.noarch.rpm
sudo yum install esl-erlang -y
安装 RabbitMQ
sudo yum install rabbitmq-server -y
(4)启动服务
sudo systemctl start rabbitmq-server
sudo systemctl enable rabbitmq-server
(5)安装management插件
sudo rabbitmq-plugins enable rabbitmq_management
(6)编辑cookie文件
确保所有节点上的 .erlang.cookie
文件内容一致,这保证了集群中的节点能够彼此识别。
查看当前的 cookie 文件内容
cat /var/lib/rabbitmq/.erlang.cookie
如果需要生成新的 cookie,则在一台机器上生成,然后复制到所有节点
sudo rabbitmq-cookie generate
复制到所有节点
sudo cp /var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie.bak
sudo cp /var/lib/rabbitmq/.erlang.cookie <other_node_ip>:/var/lib/rabbitmq/
(7)分配节点
选择一台机器作为集群的初始节点,然后让其他节点加入。
加入集群
在其他节点上执行以下命令,指定要加入的集群中的任意一个节点:
sudo rabbitmqctl stop_app
sudo rabbitmqctl join_cluster rabbit@<initial_node_hostname>
sudo rabbitmqctl start_app
验证集群状态
验证集群是否成功建立,可以在任何节点上执行:
rabbitmqctl cluster_status
注意事项
- 确保所有节点的 Erlang 版本相同。
- 如果需要持久化队列,确保磁盘节点配置正确。
- 集群中的节点必须使用相同的 Erlang cookie。
- 使用
rabbitmqctl
命令前,确保使用的是集群中的任意一个节点。