这里主要想整理关于消息队列rabbitmq可能遇到问题,躺一躺其中的坑,而后在团队沉淀下来,最终变为整个团队的技术能力,而后写着写着发现,官方文档写的都比较详细也比较好,因此抽取一些比较有价值的连接和和整理一些实际上遇到的问题和处理心得,因此这里分享出来,设计到的连接可能会相对较多。html
这里假设用户已经对rabbitmq有所了解,若是不了解,能够先按照这个方式来测试消息队列,如何使用该消息队列(官方也有完整的示例)。前端
rabbitmq是一种普遍应用于互联网的消息队列,是一种异步的消息队列,支持多种消息协议,支持多种开发语言,支持多种队列集群化方式cluster和federation,还有完善的受权机制,集群管理和支持各类插件。node
认为比较值得看的内容:mysql
我认为比较重要的几个内容linux
列举几个对集群管理相对重要的:git
一些环境变量配置:
github
注意: 这里提到的负载均衡器是4层的负载均衡,使用轮训的方式将请求转发给后端,能够假设为haproxy, lvsweb
环境:
node: rabbitmq-01, rabbitmq-02, rabbitmq-03
queue: 存在节点为非镜像队列
前端负载均衡器: TCP --> rabbitmq-01/rabbitmq-02/rabbitmq-03
需求:
2个节点须要下架,更换新的节点
rabbitmq-02 ---> rabbitmq-02-new
rabbitmq-03 ---> rabbitmq-03-new
操做:
业务低峰期将rabbitmq-02-new,rabbitmq-03-new join到集群节点,而后删除rabbitmq-01, rabbitmq-02
复制代码
开发人员推荐使用代码中建立(rabbitmq3.0后不支持...3.0后都是create ha) | 这里略坑-- --sql
queue_args={"x-ha-policy" : "all"}
channel.queue_declare{queue="hello-queue", arguments=queue_args}
复制代码
脑裂: 脑裂问题是分布式系统中最多见的问题,指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,原本为一个总体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会致使系统混乱,数据损坏。对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务,数据相关服务(好比MySQL,消息队列)的HA,必需要严格防止脑裂。(但有些生产环境下的系统按照无状态服务HA的那一套去配置有状态服务,结果可想而知...),有一些存储系统像数据库,kv存储都已经有很好的一致性协议解决了raft paxos协议解决了,这里咱们须要格外注意这里的脑裂处理流程。docker
脑裂带来的最大问题就是分区问题,分区在rabbitmq中有三种配置模式ignore(默认方式), pause_minority, autoheal
这里只测试ignore, pause_minority
环境:
node: rabbitmq-01, rabbitmq-02, rabbitmq-03
queue: 镜像队列
前端负载均衡器: TCP --> rabbitmq-01/rabbitmq-02/rabbitmq-03
复制代码
设置C-->B不能互通
复制代码
iptables -I INPUT -s {NODEX} -j REJECT 这里是表明涉及节点关闭某个ip数据包的流入
而后查看一下集群运行状态,显示已经存在分区partitions
[{nodes,
[{disc,
['rabbit@rabbitmq-test001','rabbit@rabbitmq-test002',
'rabbit@rabbitmq-test003']}]},
{running_nodes,['rabbit@rabbitmq-test003']},
{cluster_name,<<"rabbit@rabbitmq-test001">>},
{partitions,
[{'rabbit@rabbitmq-test003',
['rabbit@rabbitmq-test001','rabbit@rabbitmq-test002']}]},
{alarms,[{'rabbit@rabbitmq-test003',[]}]}]
复制代码
对应与web上看,相互检测失败,相互显示为not running
虽然ABC C-->A -->B能够通,都能逻辑互通,局部不互通仍是会出现 分区
注意点: 这时候很是重要的一点是负载均衡器存在一个较大的隐患,就是ABC互通存在问题,不过负载均衡器可以正常链接到ABC,那么请求仍是会按照正常的逻辑走,这里就容易产生数据不一致。(因为rabbitmq没有实现相似raft的分布式协议,因此这一点很重要),这就是rabbitmq集群默认分区方式ignore最大的问题,它不会自动处理,也不会有集群选举的功能,须要咱们自身手动去处理集群,去选择信任的分区模式,这里必定要格外注意,稍有差池就会致使集群状态数据异常。
选择一个你信任的分区,而后重启全部其余分区的节点,而后从新加入节点,注意其余分区节点的数据会被丢掉.
而后重启全部节点恢复警告
默认模式下,会致使脑裂,丢数据,还须要手工处理,对系统可靠性要求较高的场景必定不能使用,同时运维起来会比较麻烦,成本较高,这是系统默认的配置方式,请必定根据自身场景进行配置。
设置C-->B不能互通
复制代码
这里不会出现分区,pause_minority
赞: 这时候会有网络分区模式会自动关闭异常节点,负载均衡器也会报警,这样安全级别会较高,当节点<1/2 节点也会正常服务,当从新加入集群而后数据也能正常恢复。
rabbitmq已经一个使用普遍的消息队列,设计模式相对完善,也在移动互联网中已经被大量应用,可能正式因为这样缘由,rabbitmq有太多可配置的功能选项和隐藏配置了,因此考虑了各类各样的适用应用场景,因此若是咱们在生产环境使用,须要对它进行一个全方面的学习和掌握,针对自身的环境进行集群配置和集群调优。
列举几条本身用的相对自动的搭建流程吧,搭建3集群rabbitm-server
## 安装docker 相关的,主要是为了增长监控使用
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce -y
systemctl start docker
## 安装erlang环境与rabbitmq-server部署
sudo yum install deltarpm -y
wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-20.0.5-1.el7.centos.x86_64.rpm/download.rpm
sudo yum install -y erlang-20.0.5-1.el7.centos.x86_64.rpm
sudo yum install -y socat
#wget https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.5/rabbitmq-server-3.7.5-1.el7.noarch.rpm
wget download.hyahm.com/rabbitmq-server-3.7.5-1.el7.noarch.rpm
yum install rabbitmq-server-3.7.5-1.el7.noarch.rpm -y
chkconfig rabbitmq-server on
mkdir -p /var/data/rabbitmq && chown rabbitmq:rabbitmq /var/data/rabbitmq && chmod 755 /var/data/rabbitmq
echo 'RABBITMQ_MNESIA_BASE=/var/data/rabbitmq' >> /etc/rabbitmq/rabbitmq-env.conf
echo 'ulimit -S -n 4096' >> /etc/rabbitmq/rabbitmq-env.conf
echo 'cluster_partition_handling=pause_minority' >> /etc/rabbitmq/rabbitmq.conf
## 打开防火墙
iptables -I INPUT -p tcp -s xxxx --dport 25672 -j ACCEPT
iptables -I INPUT -p tcp -s xxx--dport 4369 -j ACCEPT
iptables -I INPUT -p tcp --dport 5672 -j ACCEPT
### 选择须要访问的内网地址
iptables -I INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -I INPUT -s 172.17.0.0/16 -j ACCEPT
复制代码
集群化:
# on rabbit1
rabbitmq-server -detached
# on rabbit2
rabbitmq-server -detached
# on rabbit3
rabbitmq-server -detached
复制代码
# on rabbit1
rabbitmqctl cluster_status
# => Cluster status of node rabbit@rabbit1 ...
# => [{nodes,[{disc,[rabbit@rabbit1]}]},{running_nodes,[rabbit@rabbit1]}]
# => ...done.
# on rabbit2
rabbitmqctl cluster_status
# => Cluster status of node rabbit@rabbit2 ...
# => [{nodes,[{disc,[rabbit@rabbit2]}]},{running_nodes,[rabbit@rabbit2]}]
# => ...done.
# on rabbit3
rabbitmqctl cluster_status
# => Cluster status of node rabbit@rabbit3 ...
# => [{nodes,[{disc,[rabbit@rabbit3]}]},{running_nodes,[rabbit@rabbit3]}]
# => ...done.
复制代码
# on rabbit2
rabbitmqctl stop_app
# => Stopping node rabbit@rabbit2 ...done.
rabbitmqctl reset
# => Resetting node rabbit@rabbit2 ...
rabbitmqctl join_cluster rabbit@rabbit1
# => Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.
rabbitmqctl start_app
# => Starting node rabbit@rabbit2 ...done.
复制代码
# on rabbit1
rabbitmqctl cluster_status
# => Cluster status of node rabbit@rabbit1 ...
# => [{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
# => {running_nodes,[rabbit@rabbit3,rabbit@rabbit2,rabbit@rabbit1]}]
# => ...done.
复制代码
systemctl start rabbitmq-server
rabbitmq-plugins enable rabbitmq_management
rabbitmqctl add_user admin xxxxxx
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
rabbitmqctl set_user_tags admin administrator
复制代码
docker run -d -e RABBIT_URL=http://{{内网Ip}}:15672 -e RABBIT_CAPABILITIES=bert,no_sort -e RABBIT_USER=admin -e RABBIT_PASSWORD=xxx -e PUBLISH_PORT=9419 -p 9419:9419 kbudde/rabbitmq-exporter
复制代码