rabbitmq+haproxy+keepalived高可用集群环境搭建

1.先安装centos扩展源:
# yum -y install epel-release

2.安装erlang运行环境以及rabbitmq
# yum install erlang
...
# yum install rabbitmq-server
...

一般yum源安装的erlang版本太低,可以从erlang官网下载打包好的rpm包手动安装,避免源码编译安装:

# wget https://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_21.0-1~centos~6_amd64.rpm
# rpm -ivh esl-erlang_21.0-1~centos~6_amd64.rpm
# wget http://www.rabbitmq.com/releases/erlang/esl-erlang-compat-18.1-1.noarch.rpm
# rpm -ivh esl-erlang-compat-18.1-1.noarch.rpm

rabbitmq资源网址:

http://www.rabbitmq.com/releases/

rabbitmq安装路径为: /usr/lib/rabbitmq/bin/

  • 启动rabbitmq
# service rabbitmq-server  start //server 监听端口5672
  • 基本配置

开启管理页面插件:

# rabbitmq-plugins enable rabbitmq_management
//如下提示表示插件启用完成
The following plugins have been enabled:
  mochiweb
  webmachine
  rabbitmq_web_dispatch
  amqp_client
  rabbitmq_management_agent
  rabbitmq_management
Plugin configuration has changed. Restart RabbitMQ for changes to take effect.
//重启rabbitmq-server
# service rabbitmq-server restart

用浏览器访问localhost:15672 即可访问web管理页面,账户名和密码均输入guest即可登录.


3.添加用户以及开启远程访问

注意: 如果是集群的话只需要在一台机器设置用户信息即可,其它会自动同步

rabbitmq的broker_url基本格式如下:

transport://userid:password@hostname:port/virtual_host

添加用户方法:

#下面创建用户密码的过程以该url为示例
broker_url = 'amqp://myuser:mypassword@localhost:5672/myvhost'

以下过程为创建用户myuser设置密码为mypassword 添加一个virtual host并允许用户访问该virtual host

$ sudo rabbitmqctl add_user myuser mypassword
$ sudo rabbitmqctl add_vhost myvhost
$ sudo rabbitmqctl set_user_tags myuser mytag
$ sudo rabbitmqctl set_permissions -p myvhost myuser ".*" ".*" ".*"

示例:

$ rabbitmqctl add_user cord 123456
$ rabbitmqctl set_user_tags cord administrator  #这里指定为管理员用户
$ rabbitmqctl set_permissions -p / cord ".*" ".*" ".*"
$ rabbitmqctl add_user af 123456
$ rabbitmqctl add_vhost af_test
$ rabbitmqctl set_user_tags af test
$ rabbitmqctl set_permissions -p af_test af ".*" ".*" ".*"

4.搭建rabbitmq集群
4.1配置各节点的hostname

提示: 编辑/etc/hosts

# vi /etc/hosts
110.55.63.51     rabbitmq1
110.55.63.52     rabbitmq2
110.55.63.220    rabbitmq3
4.2 同步.erlang.cookie文件,保证集群内节点的.erlang.cookie文件一致

.erlang.cookie的两个位置:

$home/.erlang.cookie
/var/lib/rabbitmq/.erlang.cookie

如果没有找到.erlang.cookie文件的话就先执行一下# rabbitmqctl status命令,这个命令也会提示工作空间路径

​ 如果我们使用解压缩方式安装部署的rabbitmq,那么这个文件会在home目录下,也就是home/.erlang.cookie。

​ 如果我们使用rpm等安装包方式进行安装的,那么这个文件会在/var/lib/rabbitmq目录下。

具体同步操作如下,选择一台机器,查看其.erlang.cookie值作为参考,这里以rabbitmq1的为参考:

# cat /var/lib/rabbitmq/.erlang.cookie 
OGNZTPRZEIAPZJZTQYOK

于是在其它三台机器上进行如下操作,即可完成.erlang.cookie的同步:

# echo 'OGNZTPRZEIAPZJZTQYOK' > /var/lib/rabbitmq/.erlang.cookie
4.3配置启动集群

注: 节点加入集群的前提是当前节点能通过主机名ping通要加入的集群的机器,所以上面编辑/etc/hosts文件的时候才需要将其它节点的解析也加入.

然后分别在几台服务器上分别启动rabbitmq服务:

# service rabbitmq-server start 

在rabbitmq1上执行如下创建脚本的语句(所示内容全部选中然后在终端输入,最后回车结束):

cat > rabbitmqcluster.sh<<EOF 
rabbitmqctl stop_app 
rabbitmqctl start_app 
EOF

在其它节点执行如下创建脚本的语句:

cat > rabbitmqcluster.sh<<EOF 
rabbitmqctl stop_app 
rabbitmqctl join_cluster rabbit@rabbitmq1
rabbitmqctl start_app 
EOF

然后依次对脚本添加执行权限,并依次执行脚本:

# chmod +x rabbitmqcluster.sh
# ./rabbitmqcluster.sh

执行完脚本后通过命令查看集群状态:

# rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq1' ...
[{nodes,[{disc,['rabbit@rabbitmq2','rabbit@rabbitmq1',
                'rabbit@rabbitmq3']}]},
 {running_nodes,['rabbit@rabbitmq3','rabbit@rabbitmq2',
                 'rabbit@rabbitmq1']},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{'rabbit@rabbitmq3',[]},
          {'rabbit@rabbitmq2',[]},
          {'rabbit@rabbitmq1',[]}]}]

如果配置了镜像功能后,那么其实集群中有一个磁盘节点足矣,所以可以将其它节点改为内存节点:

# rabbitmqctl stop_app
# rabbitmqctl change_cluster_node_type ram
# rabbitmqctl start_app 
# rabbitmqctl cluster_status 
Cluster status of node 'rabbit@rabbitmq1' ...
[{nodes,[{disc,['rabbit@rabbitmq1']},
         {ram,['rabbit@rabbitmq3','rabbit@rabbitmq2']}]},
 {running_nodes,['rabbit@rabbitmq3','rabbit@rabbitmq2',
                 'rabbit@rabbitmq1']},
 {cluster_name,<<"rabbit@rabbitmq1">>},
 {partitions,[]},
 {alarms,[{'rabbit@rabbitmq3',[]},
          {'rabbit@rabbitmq2',[]},
          {'rabbit@rabbitmq1',[]}]}]
4.4 配置rabbitmq镜像功能

​ 镜像队列可以同步queue和message,当主queue挂掉,从queue中会有一个变为主queue来接替工作。

​ 镜像队列是基于普通的集群模式的,所以你还是得先配置普通集群,然后才能设置镜像队列

​ 镜像队列设置后,会分一个主节点和多个从节点,如果主节点宕机,从节点会有一个选为主节点,原先的主节点起来后会变为从节点。

​ queue和message虽然会存在所有镜像队列中,但客户端读取时不论物理面连接的主节点还是从节点,都是从主节点读取数据,然后主节点再将queue和message的状态同步给从节点,因此多个客户端连接不同的镜像队列不会产生同一message被多次接受的情况。

配置镜像队列方法:

使用rabbitmqctl set_policy命令设置队列同步,其格式如下:

# rabbitmqctl set_policy [-p <vhost>] [--priority <priority>] [--apply-to <apply-to>] 

使用示例:

# rabbitmqctl set_policy  ha-all "hello" '{"ha-mode":"all"}'

​ 其中ha-all是同步模式,指同步给所有节点,还有另外两种模式:ha-exactly 表示在指定个数的节点上进行镜像,节点的个数由ha-params指定; ha-nodes表示在指定的节点上进行镜像,节点名称通过ha-params指定。

​ hello 是同步的队列名,可以用正则表达式匹配;

​ {"ha-mode":"all"} 表示同步给所有,同步模式的不同,此参数也不同。

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

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

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

​ 这行命令中^message 这个规则要根据自己修改,这个是指同步"message"开头的队列名称,我们配置时使用的应用于所有队列,所以表达式为"^"

这里我们配置vhost为af_airflow下的队列开启同步模式:

# rabbitmqctl set_policy -p af_airflow ha-allqueue "^" '{"ha-mode":"all"}' 
4.5 Haproxy+Keepalived实现rabbitmq高可用

整体结构如下图:

haproxy与keepalived介绍:

haproxy: 负载均衡,用于请求分发,类比nginx

keepalived: 高可用,这里主要保证haproxy的高可用。keepalived用于主备模型,能进行故障转移。其与haproxy的最大区别在于其不是随机分发,它只有一个活动节点,其它的为备用节点,只有当活动节点失效后,才会切换到备用节点。

a) Haproxy安装与配置:

# yum install haproxy
# vi /etc/haproxy/haproxy.cfg

在文件尾部添加如下内容(这是haproxy 1.5.18):

global
	...
	maxconn     20000 #修改全局最大连接数
	...
defaults
	...
	maxconn		20000 #修改默认最大连接数
	....

#rabbitmq的web监控平台
listen rabbitmq_admin
	bind 0.0.0.0:15672
	balance  roundrobin
    server      rabbit1 110.55.63.51:15672 
    server      rabbit2 110.55.63.52:15672 
    server      rabbit3 110.55.63.220:15672
    
# rabbitmq-server    
listen rabbitmq_cluster
    bind 0.0.0.0:5670
    option tcplog
    mode tcp
    option   clitcpka #允许客户端发送tcp keepalive包
    balance roundrobin #负载均衡的方式,roundrobin平均方式
    server   rabbit1 110.55.63.51:5672  check inter 5s rise 2 fall 3 maxconn 20000
    server   rabbit2 110.55.63.52:5672  check inter 5s rise 2 fall 3 maxconn 20000
    server   rabbit3 110.55.63.220:5672 check inter 5s rise 2 fall 3 maxconn 20000    

# Haproxy监控页面配置
listen stats
    bind 0.0.0.0:8080#设置Frontend和Backend的组合体,监控组名称(stats)可自定义
    mode http	#http的7层模式
    option httplog #采用http日志格式
    stats enable #开启功能
    stats uri /stats	#页面uri
    stats refresh 30s	#页面刷新时间
    stats auth admin:1234 #登陆账户名密码
    stats admin if TRUE #是否开启管理功能,必须跟stats auth命令

然后启动haproxy:

# haproxy -f /etc/haproxy/haproxy.cfg

重启的话使用命令service haproxy restart

监控web地址: http://110.55.63.252:8080/stats

b) keepalived安装与配置:

# yum install keepalived

分别在110.55.63.220110.55.63.252两台机器上安装keepalived

110.55.63.252上执行# vi /etc/keepalived/keepalived.conf修改如下所示:

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}
vrrp_instance VI_1 {
    interface eth0 #本机网卡名称,使用ifconfig命令查看
    state MASTER	#本机实例状态,MASTER/BACKUP,备机配置文件中请写BACKUP
    priority 200	#本机初始权重,备机请填写小于主机的值
    virtual_router_id 10	#虚拟路由编号,主备机保持一致
    unicast_src_ip 110.55.63.252
    unicast_peer {
        110.55.63.220
    }
    authentication {
        auth_type PASS
        auth_pass password
    }
    virtual_ipaddress {
        110.55.63.110  #虚地址IP,主备机保持一致
    }
    track_script {
        chk_haproxy		#对应的健康检查配置
    }
    notify_master /loadbtify_master.sh
}

同样, 在110.55.63.220上执行# vi /etc/keepalived/keepalived.conf修改如下所示:

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}
vrrp_instance VI_1 {
    interface eth0
    state BACKUP
    priority 100
    virtual_router_id 10
    unicast_src_ip 110.55.63.220
    unicast_peer {
        110.55.63.252
    }
    authentication {
        auth_type PASS
        auth_pass password
    }
    virtual_ipaddress {
        110.55.63.110
    }
    track_script {
        chk_haproxy
    }
    notify_master /loadbtify_master.sh
}

然后分别启动keepalived服务:

# service keepalived start

检测服务情况:

# telnet 110.55.63.110 5670
Trying 110.55.63.110...
Connected to 110.55.63.110.
Escape character is '^]'.
.....

而访问rabbitmq的时候使用的url为: amqp://af:123456@110.55.63.110:5670/af_airflow

至此安装结束。

5.性能测试

首先下载官方提供的rabbitmq测试工具perf-test,下载地址如下:

https://bintray.com/rabbitmq/java-tools/perf-test

下载rabbitmq-perf-test-2.1.2-bin.zip之后将其上传至测试服务器,然后解压并执行测试命令:

#解压
# unzip rabbitmq-perf-test-2.1.2-bin.zip   
#进入bin路径
# cd rabbitmq-perf-test-2.1.2/bin
# ./runjava com.rabbitmq.perf.PerfTest -h amqp://af:123456@110.55.63.110:5670/af_airflow -s 1024 -x 3 -y 5 -u "throughput-test-1" -a --id "test 2"

id: test 2, starting consumer #0
id: test 2, starting consumer #0, channel #0
id: test 2, starting consumer #1
id: test 2, starting producer #0, channel #0
id: test 2, starting producer #1
id: test 2, starting producer #1, channel #0
id: test 2, time: 1.000s, sent: 2933 msg/s, received: 2195 msg/s, min/median/75th/95th/99th latency: 4037/99846/124546/141881 ?s
id: test 2, time: 2.000s, sent: 13179 msg/s, received: 11736 msg/s, min/median/75th/95th/99th latency: 6891/59613/110383/269429 ?s
id: test 2, time: 3.011s, sent: 13992 msg/s, received: 15163 msg/s, min/median/75th/95th/99th latency: 12047/89519/189558/589848 ?s

命令参数说明:

-x 生产者个数
-y 消费者个数
-s 指定消息字节数,默认12字节
-u 队列名
-a 自动ack确认
--id 测试id

测试结果(三个节点组成集群):

服务器硬件信息(虚拟机环境):

cpu:二路四核,主频2.2ghz

mem: 32GB

消息大小(byte) 吞吐量(msg/s) 负载
12 11000~13000 cpu: %270 mem: %0.3
1024 7000~8500 cpu: %211 mem: %0.3

常用命令:
# rabbitmqctl add_user root root //用户名密码都是root
# rabbitmqctl list_queues 查看等待队列
# rabbitmqctl stop_app 停止节点
# rabbitmqctl reset  重置节点
# rabbitmqctl start_app 启动节点
# rabbitmqctl cluster_status 查看集群状态
# rabbitmqctl change_cluster_node_type disc/ram –更改节点为磁盘或内存节点
# rabbitmqctl set_policy  ha-all "hello" '{"ha-mode":"all"}' 将"hello"的队列设置为同步给其它节点,即开启高可用模式
# rabbitmqctl forget_cluster_node rabbit@rabbit1 将节点从集群中移除

参考链接:

http://www.jianshu.com/p/7e2e3b25fccf

http://www.cnblogs.com/huchong/p/8491107.html?utm_source=tuicool&utm_medium=referral

http://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html

https://www.cnblogs.com/grimm/p/5771038.html

https://www.linuxidc.com/Linux/2012-10/72720.htm

https://www.cnblogs.com/lion.net/p/5725474.html

https://www.cnblogs.com/MacoLee/p/5853413.html

https://blog.csdn.net/luxianping/article/details/52270439

原文地址:https://www.cnblogs.com/cord/p/9242459.html