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.220
和110.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