热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux-rabbit集群部署+ha

http:www.cnblogs.comtelwanggsp7124832.htmlhttp:www.ywnds.com?p4741https:

    http://www.cnblogs.com/telwanggs/p/7124832.html

http://www.ywnds.com/?p=4741

   https://blog.csdn.net/u013256816/article/details/77150922


集群理论知识:

由于RabbitMQ是用erlang开发的,RabbitMQ完全依赖Erlang的Cluster,因为erlang天生就是一门分布式语言,集群非常方便,但其本身并不支持负载均衡。Erlang的集群中各节点是经由过程一个magic COOKIE来实现的,这个COOKIE存放在 $home/.erlang.COOKIE 中(像我的root用户安装的就是放在我的root/.erlang.COOKIE中),文件是400的权限。所以必须包管各节点COOKIE对峙一致,不然节点之间就无法通信。

RabbitMQ的集群节点包括内存节点、磁盘节点。顾名思义内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘。不过,如果在投递消息时,打开了消息的持久化,那么即使是内存节点,数据还是安全的放在磁盘。


 Rabbitmq集群大概分为二种方式:

(1)普通模式:默认的集群模式。

(2)镜像模式:把需要的队列做成镜像队列。

一个rabbitmq集 群中可以共享 user,vhost,queue,exchange等,所有的数据和状态都是必须在所有节点上复制的,一个例外是,那些当前只属于创建它的节点的消息队列,尽管它们可见且可被所有节点读取。rabbitmq节点可以动态的加入到集群中,一个节点它可以加入到集群中,也可以从集群环境中移除。
   集群中有两种节点:
1 内存节点:只保存状态到内存(一个例外的情况是:持久的queue的持久内容将被保存到disk)
2 磁盘节点:保存状态到内存和磁盘。
内存节点虽然不写入磁盘,但是它执行比磁盘节点要好。集群中,只需要一个磁盘节点来保存状态 就足够了如果集群中只有内存节点,那么不能停止它们,否则所有的状态,消息等都会丢失。

良好的设计架构可以如下:在一个集群里,有3台以上机器,其中1台使用磁盘模式,其它使用内存模式。其它几台为内存模式的节点,无疑速度更快,因此客户端(consumer、producer)连接访问它们。而磁盘模式的节点,由于磁盘IO相对较慢,因此仅作数据备份使用。

一、普通模式:默认的集群模式

默认的集群模式,queue创建之后,如果没有其它policy,则queue就会按照普通模式集群。对于Queue来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构,但队列的元数据仅保存有一份,即创建该队列的rabbitmq节点(A节点),当A节点宕机,你可以去其B节点查看,./rabbitmqctl list_queues 发现该队列已经丢失,但声明的exchange还存在。当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer,所以consumer应平均连接每一个节点,从中取消息。该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。如果做了队列持久化或消息持久化,那么得等A节点恢复,然后才可被消费,并且在A节点恢复之前其它节点不能再创建A节点已经创建过的持久队列;如果没有持久化的话,消息就会失丢。这种模式更适合非持久化队列,只有该队列是非持久的,客户端才能重新连接到集群里的其他节点,并重新创建队列。假如该队列是持久化的,那么唯一办法是将故障节点恢复起来。
为什么RabbitMQ不将队列复制到集群里每个节点呢?这与它的集群的设计本意相冲突,集群的设计目的就是增加更多节点时,能线性的增加性能(CPU、内存)和容量(内存、磁盘)。理由如下

1。存储空间:如果每个集群节点每个队列的一个完整副本,增加节点需要更多的存储容量。例如,如果一个节点可以存储1 gb的消息,添加两个节点需要两份相同的1 gb的消息
2。性能:发布消息需要将这些信息复制到每个集群节点。对持久消息,要求为每条消息触发磁盘活动在所有节点上。每次添加一个节点都会带来 网络和磁盘的负载。

当然RabbitMQ新版本集群也支持队列复制(有个选项可以配置)。比如在有五个节点的集群里,可以指定某个队列的内容在2个节点上进行存储,从而在性能与高可用性之间取得一个平衡(应该就是指镜像模式)。

二、镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案(镜像模式是在普通模式的基础上,增加一些镜像策略)

该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置policy,然后客户端创建队列的时候,rabbitmq集群根据“队列名称”自动设置是普通集群模式或镜像队列。具体如下:
队列通过策略来使能镜像。策略能在任何时刻改变,rabbitmq队列也近可能的将队列随着策略变化而变化;非镜像队列和镜像队列之间是有区别的,前者缺乏额外的镜像基础设施,没有任何slave,因此会运行得更快。为了使队列称为镜像队列,你将会创建一个策略来匹配队列,设置策略有两个键“ha-mode和 ha-params(可选)”。ha-params根据ha-mode设置不同的值,下面表格说明这些key的选项:

语法讲解:

在cluster中任意节点启用策略,策略会自动同步到集群节点  (hrsystem  一般"/")

rabbitmqctl set_policy -p hrsystem ha-allqueue"^" '{"ha-mode":"all"}'

rabbitmqctl set_policy -p / ha-all "^" '{"ha-mode":"all"}'

这行命令在vhost名称为hrsystem创建了一个策略,策略名称为ha-allqueue,策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。

例如rabbitmqctl set_policy -p hrsystem ha-allqueue "^message" '{"ha-mode":"all"}'

rabbitmqctl set_policy -p / ha-all "^message" '{"ha-mode":"all"}'

注意:"^message" 这个规则要根据自己修改,这个是指同步"message"开头的队列名称,我们配置时使用的应用于所有队列,所以表达式为"^"
官方set_policy说明参见
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]

“nodes”策略和迁移master

需要注意的是设置和修改一个“nodes”策略将不会引起已经存在的master离开,尽管你让其离开。比如:如果一个队列在{A},并且你给它一个节点策略告知它在{B C},它将会在{A B C}。如果节点A那时失败或者停机了,那个节点上的镜像将不回来且队列将继续保持在{B C}(注:当队列已经是镜像队列且同步到其它节点,就算原节点宕机,也不影响其它节点对此队列使用)。


队列名称以“ha.”开头的队列都是镜像队列,镜像到集群内所有节点:


列名称以“two.”开头的队列,其策略镜像到集群内任何两个节点:


队列同步到指rabbitmq 节点  ,rabbitmqctl:

./rabbitmqctl set_policy sa-specify "^sa\.specify\." '{"ha-mode":"nodes","ha-params":["rabbit@is137","rabbit@raxtone"]}' 

切记,需要把队列同步到的节点都写进去。


4台机器  44、45、46,47,前3台部署rabbitmq,后一台部署ha

1. 修改主机名称 zcy44,zcy45,zcy46,zcy47(参考之前的blog)

 hostnamectl --static set-hostname zcy44

重启命令:reboot

2. 修改/etc/hosts (44,45,46 三台集群的hosts文件中添加以下,同步主机的/etc/hosts文件

172.18.8.44  zcy44
172.18.8.45  zcy45

172.18.8.46  zcy46

3. 3台主机分别安装rabbitmq

    在3台主机上分别安装rabbitmq ,并且启动,并且打开管理界面

  安装参考另一个blog

3. 同步erlang.COOKIE文件 (此文件是隐藏,所以ls -al )

Erlang COOKIE 文件:/var/lib/rabbitmq/.erlang.COOKIE。这里将 node1 的该文件复制到 node2、node3,由于这个文件权限是 400,所以需要先修改 node2、node3 中的该文件权限为 777

然后将 node1 中的该文件拷贝到 node2、node3,最后将权限和所属用户/组修改回来

4. 加入集群

1> zcy44 上启动(命令必须是这样):service rabbitmq-server start

在zcy44节点上查看集群信息,此时集群中应只有自己

rabbitmqctl cluster_status

root @ live - mq - 01 : ~ # rabbitmqctl cluster_status
Cluster status of node 'rabbit@zcy44' . . .
[
{ nodes , [ { disc , [ 'rabbit@zcy44' ] } ] } ,
#集群中的节点,disc表示为磁盘模式,ram表示为内存模式
{ running_nodes , [ 'rabbit@zcy44' ] } ,
#正在运行的集群节点
{ cluster_name , << "rabbit@zcy44" >> } ,
#集群的名称
{ partitions , [ ] }
]

2> 下面zcy44,45,46 组成集群:

在zcy45上面先用service rabbitmq-server start启动,执行 rabbitmqctl cluster_status 看看,然后执行以下

在zcy46上面先用service rabbitmq-server start启动,执行 rabbitmqctl cluster_status 看看,然后执行以下

此时 node2 与 node3 也会自动建立连接;如果要使用内存节点,则可以使用
node2 # rabbitmqctl join_cluster  --ram rabbit@node1 加入集群。当然可以不用

3> 在任何一台节点上执行 rabbitmqctl cluster_status (结果忽略,贴的别人),反正就是3台现在集群了

root @ live - mq - 01 : ~ # rabbitmqctl cluster_status
Cluster status of node 'rabbit@zcy44' . . .
[ { nodes , [ { disc , [ 'rabbit@live-mq-01' ] } ,
{ ram , [ 'rabbit@live-mq-03' , 'rabbit@live-mq-02' ] } ] } ,
{ running_nodes , [ 'rabbit@live-mq-02' , 'rabbit@live-mq-03' , 'rabbit@live-mq-01' ] } ,
{ cluster_name , << "rabbit@live-mq-01" >> } ,
{ partitions , [ ] } ]


5. 设置镜像队列策略

在任意一个节点上执行:
 r abbitmqctl set_policy -p / ha-all "^" '{"ha-mode":"all"}'
将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一直。
rabbitmqctl list_policies 查看策略

6. 同步队列

rabbitmqctl sync_queue ryttest。 或者在rabbitmq 界面上点击队列,然后同步

6. 安装并配置 HAProxy及配置 (43主机)

1>安装

yum install haproxy

2>修改 /etc/haproxy/haproxy.cfg (注意红色部分,其他不修改)

#全局配置
global
        #日志输出配置,所有日志都记录在本机,通过local0输出
        log 127.0.0.1 local0 info
        #最大连接数
        maxconn 4096
        #改变当前的工作目录
        chroot /opt/haproxy-1.7.8
        #以指定的UID运行haproxy进程
        uid 99
        #以指定的GID运行haproxy进程
        gid 99
        #以守护进程方式运行haproxy #debug #quiet
        daemon
        #debug
        #当前进程pid文件
        pidfile /opt/haproxy-1.7.8/haproxy.pid


#默认配置
defaults
        #应用全局的日志配置
        log global
        #默认的模式mode{tcp|http|health}
        #tcp是4层,http是7层,health只返回OK
        mode tcp
        #日志类别tcplog
        option tcplog
        #不记录健康检查日志信息
        option dontlognull
        #3次失败则认为服务不可用
        retries 3
        #每个进程可用的最大连接数
        maxconn 2000
        #连接超时
        timeout connect 5s
        #客户端超时
        timeout client 120s
        #服务端超时
        timeout server 120s


#绑定配置

listen rabbitmq_cluster 

 bind 43主机ip:5672

        #配置TCP模式
        mode tcp
        #简单的轮询
        balance roundrobin
        #RabbitMQ集群节点配置
        server zcy44 192.168.0.2:5672 check inter 5000 rise 2 fall 3 weight 1
        server zcy45 192.168.0.3:5672 check inter 5000 rise 2 fall 3 weight 1
        server zcy46 192.168.0.4:5672 check inter 5000 rise 2 fall 3 weight 1


#haproxy监控页面地址

listen monitor 

 bind 43ip:8100

        mode http
        option httplog
        stats enable
        stats uri /stats

        stats refresh 5s

在上面的配置中“listen rabbitmq_cluster bind 192.168.0.9.5671”这里定义了客户端连接IP地址和端口号。这里配置的负载均衡算法是roundrobin,注意这里的roundrobin是加权轮询。和RabbitMQ最相关的是“ server rmq_node1 192.168.0.2:5672 check inter 5000 rise 2 fall 3 weight 1”这种,它定义了RabbitMQ服务,每个RabbitMQ服务定义指令包含6个部分

server :定义RabbitMQ服务的内部标示,注意这里的“rmq_node”是指包含有含义的字符串名称,不是指RabbitMQ的节点名称。
::定义RabbitMQ服务的连接的IP地址和端口号。
check inter :定义了每隔多少毫秒检查RabbitMQ服务是否可用。
rise :定义了RabbitMQ服务在发生故障之后,需要多少次健康检查才能被再次确认可用。
fall :定义需要经历多少次失败的健康检查之后,HAProxy才会停止使用此RabbitMQ服务。
weight :定义了当前RabbitMQ服务的权重。

最后一段配置定义的是HAProxy的数据统计页面。数据统计页面包含各个服务节点的状态、连接、负载等信息。在调用

haproxy -f haproxy.cfg

行HAProxy之后可以在浏览器上输入http://192.168.0.9:8100/stats来加载相关的页面

7.其他

1> 磁盘节点改成内存节点

    如果想把live-mq-02由磁盘节点改成内存节点

此时live-mq-02与live-mq-03也会自动建立连接,上面我的两个节点,其中live-mq-02是磁盘节点,live-mq-03是内存节点,但live-mq-01节点默认是磁盘节点(一个集群中最少要有一个磁盘节点)。如果想把live-mq-02由磁盘节点改成内存节点,使用如下change_cluster_node_type命令修改即可,但要先stop:

2> RabbitMQ退出集群

假设要把rabbit@live-mq-02退出集群,在rabbit@live-mq-02上执行:

或者:

在集群主节点上执行

3> RabbitMQ集群重启

集群重启时,最后一个挂掉的节点应该第一个重启,如果因特殊原因(比如同时断电),而不知道哪个节点最后一个挂掉。可用以下方法重启:

先在一个节点上执行

在其他节点上执行

查看cluster状态是否正常(要在所有节点上查询)。

如果有节点没加入集群,可以先退出集群,然后再重新加入集群。




推荐阅读
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 双指针法在链表问题中应用广泛,能够高效解决多种经典问题,如合并两个有序链表、合并多个有序链表、查找倒数第k个节点等。本文将详细介绍这些应用场景及其解决方案。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 探讨Redis的最佳应用场景
    本文将深入探讨Redis在不同场景下的最佳应用,包括其优势和适用范围。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • Ansible:自动化运维工具详解
    Ansible 是一款新兴的自动化运维工具,基于 Python 开发,集成了多种运维工具(如 Puppet、CFEngine、Chef、Func 和 Fabric)的优点,实现了批量系统配置、程序部署和命令执行等功能。本文将详细介绍 Ansible 的架构、特性和优势。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 如何将Python与Excel高效结合:常用操作技巧解析
    本文深入探讨了如何将Python与Excel高效结合,涵盖了一系列实用的操作技巧。文章内容详尽,步骤清晰,注重细节处理,旨在帮助读者掌握Python与Excel之间的无缝对接方法,提升数据处理效率。 ... [详细]
  • 深入解析 Synchronized 锁的升级机制及其在并发编程中的应用
    深入解析 Synchronized 锁的升级机制及其在并发编程中的应用 ... [详细]
  • 深入解析C语言中结构体的内存对齐机制及其优化方法
    为了提高CPU访问效率,C语言中的结构体成员在内存中遵循特定的对齐规则。本文详细解析了这些对齐机制,并探讨了如何通过合理的布局和编译器选项来优化结构体的内存使用,从而提升程序性能。 ... [详细]
author-avatar
枝断叶残_337
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有