linux-rabbit集群部署+ha

    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 看看,然后执行以下

1
2
3
root @ live - mq - 02 : ~ # rabbitmqctl stop_app
root @ live - mq - 02 : ~ # rabbitmqctl join_cluster rabbit@zcy44
root @ live - mq - 02 : ~ # rabbitmqctl start_app

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

 
1
2
3
root @ live - mq - 03 : ~ # rabbitmqctl stop_app
root @ live - mq - 03 : ~ # rabbitmqctl join_cluster rabbit@zcy44 --ram
root @ live - mq - 03 : ~ # rabbitmqctl start_app
此时 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. 设置镜像队列策略

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

6. 同步队列

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

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

https://www.jianshu.com/p/2bee5e32deeb

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

#---------------------------------------------------------------------
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    #option forwardfor       except 127.0.0.0/8#注意这行得注释掉,不然报错
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

#---------------------------------------------------------------------
#---------------------------------------------------------------------
#对MQ集群进行监听
listen rabbitmq_cluster
    bind 0.0.0.0:5673   #通过5673对m1和m2进行映射
    option tcplog       #记录TCP连接状态和时间
    mode tcp            #四层协议代理,即对TCP进行转发
    option clitcpka     #开启TCP的Keep Alive(长连接模式)
    timeout connect 1s  #haproxy与mq建立连接的超时时间
    timeout client 10s  #客户端与haproxy最大空闲时间
    timeout server 10s  #服务器与haproxy最大空闲时间
    balance roundrobin  #采用轮询转发消息
    #每5秒发送一次心跳包,如果连续两次有响应则代表状态良好
    #如果连续3次没有响应,则视为服务故障,该节点将被剔除
    server 85node 192.168.7.85:5672 check inter 5s rise 2 fall 3
    server 86node 192.168.7.86:5672 check inter 5s rise 2 fall 3
    server 87node 192.168.7.87:5672 check inter 5s rise 2 fall 3

listen rabbitmq_admin
    bind 0.0.0.0:8100
    server 85node 192.168.7.85:15672
    server 86node 192.168.7.86:15672
    server 87node 192.168.7.87:15672

#开启监控服务
listen http_front
    bind 0.0.0.0:1080          #监听端口
    stats refresh 30s          #每30秒刷新一次
    stats uri /haproxy?stats   #统计页面uri
    stats auth admin123:admin123     #统计页面用户名和密码设置

#---------------------------------------------------------------------
#---------------------------------------------------------------------

 

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

1
2
3
4
5
6
7
8
9
root @ live - mq - 02 : ~ # rabbitmqctl stop_app
Stopping node 'rabbit@live-mq-02' . . .
. . .done .
root @ live - mq - 02 : ~ # rabbitmqctl change_cluster_node_type ram
Turning 'rabbit@live-mq-02' into a ram node . . .
. . .done .
root @ live - mq - 02 : ~ # rabbitmqctl start_app
Starting node 'rabbit@live-mq-02' . . .
. . .done .

2> RabbitMQ退出集群

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

1
2
3
$ rabbitmqctl stop _app
$ rabbitmqctl reset
$ rabbitmqctl start_app

或者:

在集群主节点上执行

1
$ rabbitmqctl forget_cluster _node  rabbit @ live - mq - 02

3> RabbitMQ集群重启

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

先在一个节点上执行

1
2
$ rabbitmqctl force _boot
$ service rabbitmq - server start

在其他节点上执行

1
$ service rabbitmq - server start

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

1
rabbitmqctl cluster_status

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

队列删除不了,处理方式:

  • 输入命令rabbitmqctl list_queues,有2万多条数据

  • 关闭应用

    rabbitmqctl stop_app

    执行清除命令

  • rabbitmqctl reset

    启动应权用

  • rabbitmqctl start_app

    验证清除结果rabbitmqctl list_queues

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值