消息队列之RabbitMQ
Posted yt丶独自
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息队列之RabbitMQ相关的知识,希望对你有一定的参考价值。
1.1 RabbitMQ 简介:
RabbitMQ 采用 Erlang 语言开发,Erlang 语言由 Ericson 设计,Erlang 在分布式编程和故障恢复方面表现出色,电信领域被广泛使用。
Erlang语言官方网址:https://www.erlang.org/
Broker: 接收和分发消息的应用,RabbitMQ Server 就是 Message Broker。
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念,当多个不同的用户使用同一个RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost创建 exchange/queue 等。
Connection:publisher/consumer 和 broker 之间的 TCP 连接。
Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection极大减少了操作系统建立 TCP connection 的开销。
Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到 queue 中去。常用的类型有:direct (point-to-point),topic (publish-subscribe) and fanout (multicast)。
Queue:消息最终被送到这里等待 consumer 取走。
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。
RabbitMQ的优势:
1、基于 erlang 语言开发,具有高并发优点、支持分布式;
2、具有消息确认机制、消息持久化机制,消息可靠性和集群可靠性高;
4、开源。
Queue 的特性:
1、消息基于先进先出的原则进行顺序消费;
2、消息可以持久化到磁盘节点服务器;
3、消息可以缓存到内存节点服务器提高性能。
生产者发送消息到 broker server(RabbitMQ),在 Broker 内部,用户创建
Exchange/Queue,通过 Binding 规则将两者联系在一起,Exchange 分发消息,根据类型/binding 的不同分发策略有区别,消息最后来到 Queue 中,等待消费者取走。
JMS 是在 2001 年发布的 Java 消息服务(Java Message Service)应用程序接口,是一个 Java 平台中关于面向消息中间件(MOM,message oriented middleware)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
官网下载地址:
https://www.rabbitmq.com/download.html
github下载地址:
https://github.com/rabbitmq/rabbitmq-server/releases
1.3.1 ubuntu1804部署单机版RabbitMQ
官方参考: https://www.rabbitmq.com/install-debian.html
1.3.1.1 主机名解析:在当前MQ服务器配置本地主机名解析
#编辑hosts文件,添加本地主机名解析 root@ubuntu1804-40:~# vim /etc/hosts 10.0.0.40 ubuntu1804-40 #测试是否添加成功 root@ubuntu1804-40:~# ping ubuntu1804-40 PING ubuntu1804-40 (10.0.0.40) 56(84) bytes of data. 64 bytes from ubuntu1804-40 (10.0.0.40): icmp_seq=1 ttl=64 time=0.033 ms 64 bytes from ubuntu1804-40 (10.0.0.40): icmp_seq=2 ttl=64 time=0.030 ms
1.3.1.2 服务器安装RabbitMQ
#安装基础命令及添加key sudo apt-get -y install curl gnup curl -1sLf \'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey\' | sudo apt-key add - #安装apt HTTPS传输 sudo apt-get -y install apt-transport-https #添加apt源 sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF deb http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main deb-src http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main deb-src https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main EOF #更新apt源 sudo apt update #查看可安装的RabbitMQ版本 sudo apt-cache madison rabbitmq-server #安装erlang sudo apt-get install -y erlang-base \\ erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \\ erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \\ erlang-runtime-tools erlang-snmp erlang-ssl \\ erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl #安装RabbitMQ sudo apt-get install rabbitmq-server -y --fix-missing
1.3.1.3 启动RabbitMQ
#启动RabbitMQ,ubuntu安装完成后自动启动 systemctl start rabbitmq-server.service #停止RabbitMQ systemctl stop rabbitmq-server.service #查看RabbitMQ状态 systemctl status rabbitmq-server.service
1.3.1.4 RabbitMQ常用命令
#查看节点状态
rabbitmqctl status
#查看所有可用插件 rabbitmq-plugins list #启用插件 rabbitmq-plugins enable <plugin-name> #停用插件 rabbitmq-plugins disable <plugin-name>
#列出所有用户 rabbitmqctl list_users #添加用户 rabbitmqctl add_user <username> <password> #删除用户 rabbitmqctl delete_user <username> #清除用户权限 rabbitmqctl clear_permissions -p vhostpath <username> #列出用户权限 rabbitmqctl list_user_permissions <username> #设置用户权限 rabbitmqctl set_permissions -p vhostpath <username> ".*" ".*" ".*" #修改用户密码 rabbitmqctl change_password <username> <newpassword>
官方参考:https://www.rabbitmq.com/management.html
#开启web界面管理插件
rabbitmq-plugins enable rabbitmq_management
5672:消费者访问端口
15672:web管理端口
登录地址:服务器ip:15672
RabbitMQ从3.3.0开始禁止使用guest/guest权限通过除了localhost外的访问,直接访问会报以下错误:
登录web界面方法:
#由于我的RabbitMQ版本是3.8.16,没有rabbit.app文件,只能重新添加用户并授权 #添加用户 rabbitmqctl add_user <username> <password> #设置添加的用户为管理员 rabbitmqctl set_user_tags <username> administrator #赋予权限 rabbitmqctl set_permissions -p / <username> ".*" ".*" ".*" #重启服务 systemctl restart rabbitmq-server.service
Rabbitmq 集群分为二种方式:
普通模式:创建好 RabbitMQ 集群之后的默认模式。
镜像模式:把需要的队列做成镜像队列。
普通集群模式:
queue 创建之后,如果没有其它 policy,消息实体只存在于其中 一个节点,A、B 两个 Rabbitmq 节点仅有相同的元数据,即队列结构,但队列的数据仅保存有一份,即创建该队列的 rabbitmq 节点(A 节点),当消息进入 A 节 点的 Queue 中后,consumer 从 B 节点拉取时,RabbitMQ 会临时在 A、B 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer,所以 consumer 可以连接每一个节点,从中取消息,该模式存在一个问题就是当 A 节点故障后,B 节点无法取到 A 节点中还未消费的消息实体。
镜像集群模式:
把需要的队列做成镜像队列,存在于多个节点,属于 RabbitMQ 的 HA 方案(镜 像模式是在普通模式的基础上,增加一些镜像策略) 该模式解决了普通模式中的数据丢失问题,其实质和普通模式不同之处在于,消 息实体会主动在镜像节点间同步,而不是在 consumer 取数据时临时拉取,该模 式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之 大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置 policy, 然后客户端创建队列的时候,rabbitmq 集群根据“队列名称”自动设置是普通集群模式或镜像队列。
集群种有两种节点类型:
内存节点:只将数据保存到内存。
磁盘节点:保存数据到内存和磁盘。
内存节点虽然不写入磁盘,但是它执行比磁盘节点要好,集群中,只需要一个 磁盘节点来保存数据就足够了如果集群中只有内存节点,那么不能全部停止它 们,否则所有数据消息在服务器全部停机之后都会丢失。
在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式,其它节 点使用内存模式,内存节点无访问速度更快,由于磁盘 IO 相对较慢,因此可作为数据备份使用。
1.4.1 debian10部署RabbitMQ集群
环境配置:10.0.0.10,10.0.0.20,10.0.0.30
1.4.1.1 主机名解析配置
各 RabbitMQ 服务器配置本地主机名解析:
10.0.0.10 debian10-10 10.0.0.20 debian10-20 10.0.0.30 debian10-30
#安装基础命令依赖及添加key sudo apt-get install curl gnupg debian-keyring debian-archive-keyring apt-transport-https -y sudo apt-key adv --keyserver "hkps://keys.openpgp.org" --recv-keys "0x0A9AF2115F4687BD29803A206B73A36E6026DFCA" sudo apt-key adv --keyserver "keyserver.ubuntu.com" --recv-keys "F77F1EDA57EBB1CC" curl -1sLf \'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey\' | sudo apt-key add - #添加apt源 sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF deb https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian buster main deb-src https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian buster main deb https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian buster main deb-src https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian buster main EOF #更新apt源 sudo apt update #查看可安装的RabbitMQ版本 sudo apt-cache madison rabbitmq-server #安装erlang sudo apt-get install -y erlang-base \\ erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \\ erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \\ erlang-runtime-tools erlang-snmp erlang-ssl \\ erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl #安装RabbitMQ sudo apt-get install rabbitmq-server -y --fix-missing
1.4.1.3 创建RabbitMQ集群
debian10的ssh默认不能使用密码登录,如需使用scp,则需要修改/etc/ssh/sshd_config文件 需要将PermitRootLogin no / without-password 改为 PermitRootLogin yes 重启ssh服务:systemctl restart sshd
拷贝前需要停止RabbitMQ服务。
systemctl stop rabbitmq-server.service
将节点1上的erlang.cookie文件拷贝到节点2和节点3服务器。
scp /var/lib/rabbitmq/.erlang.cookie 10.0.0.20:/var/lib/rabbitmq/.erlang.cookie scp /var/lib/rabbitmq/.erlang.cookie 10.0.0.30:/var/lib/rabbitmq/.erlang.cookie
查看节点1的集群名称,并将其余2个节点加入到集群
#查看节点1的集群名称 root@debian10-10:/# rabbitmqctl cluster_status Cluster status of node rabbit@debian10-10 ... #加入集群,以内存节点的模式 root@debian10-20:~# rabbitmqctl join_cluster rabbit@debian10-10 --ram root@debian10-30:~# rabbitmqctl join_cluster rabbit@debian10-10 --ram #再次查看节点状态 #3.7X版本 root@debian10-10:/# rabbitmqctl cluster_status Cluster status of node rabbit@debian10-10 ... [{nodes,[{disc,[\'rabbit@debian10-10\']}, {ram,[\'rabbit@debian10-30\',\'rabbit@debian10-20\']}]}, {running_nodes,[\'rabbit@debian10-30\',\'rabbit@debian10-20\', \'rabbit@debian10-10\']}, {cluster_name,<<"rabbit@debian10-10">>}, {partitions,[]}, {alarms,[{\'rabbit@debian10-30\',[]}, {\'rabbit@debian10-20\',[]}, {\'rabbit@debian10-10\',[]}]}] #3.8.X版本 rabbitmqctl cluster_status Cluster status of node rabbit@mq-server2 ... Basics Cluster name: rabbit@mq-server2 Disk Nodes rabbit@mq-server2 Running Nodes rabbit@mq-server2 Versions rabbit@mq-server2: RabbitMQ 3.8.3 on Erlang 22.3
要在web界面上看到3个节点正常,需要每个节点都开启web界面。
#开启RabbitMQ的web界面
rabbitmq-plugins enable rabbitmq_management
以上是关于消息队列之RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章