RabbitMQ3.6.3集群搭建+HAProxy1.6作负载均衡

目录

[TOC]html

一、基本概念

1.一、RabbitMQ集群概述

  经过 Erlang 的分布式特性(经过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每一个节点都提供服务给客户端链接,进行消息发送与接收。node

  这些节点经过 RabbitMQ HA 队列(镜像队列)进行消息队列结构复制。本方案中搭建 3 个节点,而且都是磁盘节点(全部节点状态保持一致,节点彻底对等),只要有任何一个节点可以工做,RabbitMQ 集群对外就能提供服务。mysql

1.二、软件负载均衡器HAProxy

  HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速而且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。HAProxy支持从4层至7层的网络交换,即覆盖全部的TCP协议。就是说,Haproxy 甚至还支持 Mysql 的均衡负载。golang

  HAProxy的特色是:
  一、HAProxy是支持虚拟主机的,,并能支持上万级别的链接;
  二、可以补充Nginx的一些缺点好比Session的保持,cookie的引导等工做;
  三、支持url检测后端的服务器出问题的检测会有很好的帮助;
  四、它跟LVS同样,自己仅仅就只是一款负载均衡软件;单纯从效率上来说HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的;
  五、HAProxy能够对mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,因此我向你们推荐LVS+Keepalived;
  六、可以提供4层,7层代理。HAProxy支持两种主要的代理模式:"tcp"也即4层(大多用于邮件服务器、内部协议通讯服务器等),和7层(HTTP)。在4层模式 下,HAProxy仅在客户端和服务器之间转发双向流量,7层模式下,HAProxy会分析协议,而且能经过容许、拒绝、交换、增长、修改或者删除请求 (request)或者回应(response)里指定内容来控制协议,这种操做要基于特定规则;
  七、HAProxy的算法如今也愈来愈多了,具体有以下8种:
     ①roundrobin,表示简单的轮询,这个很少说,这个是负载均衡基本都具有的;
     ②static-rr,表示根据权重,建议关注;
     ③leastconn,表示最少链接者先处理,建议关注;
     ④source,表示根据请求源IP,这个跟Nginx的IP_hash机制相似,咱们用其做为解决session问题的一种方法,建议关注;
     ⑤ri,表示根据请求的URI;
     ⑥rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name;
     ⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
     ⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。web

二、RabbitMQ的配置步骤

2.一、安装 Erlang、RabbitMQ

  参考文章Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践正则表达式

2.二、修改 /etc/hosts

  加入集群 3 个节点的对应关系:redis

192.168.0.31 node1
192.168.0.32 node2
192.168.0.33 node3算法

2.二、设置 Erlang Cookie

  RabbitMQ节点之间和命令行工具 (e.g. rabbitmqctl)是使用Cookie互通的,Cookie是一组随机的数字+字母的字符串。当RabbitMQ服务器启动的时候,Erlang VM会自动建立一个随机内容的Cookie文件。若是是经过源安装RabbitMQ的话,Erlang Cookie 文件在/var/lib/rabbitmq/.erlang.cookie。若是是经过源码安装的RabbitMQ,Erlang Cookie文件$HOME/.erlang.cookie。sql

  本文演示的实例是用源码安装,因为这个文件权限是 400,因此须要先修改 node二、node3 中的该文件权限为 777:ubuntu

lion@node1:~$ chmod 777 .erlang.cookie

  而后将文件复制到node二、node3上面。

node2:

lion@node2:~$ chmod 777 .erlang.cookie
lion@node2:~$ scp -r node1:/home/lion/.erlang.cookie ~/
lion@node1's password:
.erlang.cookie                                                                                     100%   20     0.0KB/s   00:00

node3:

lion@node3:~$ chmod 777 .erlang.cookie
lion@node3:~$ scp -r node1:/home/lion/.erlang.cookie ~/
lion@node1's password:
.erlang.cookie                                                                                     100%   20     0.0KB/s   00:00

  分别在node一、node二、node3将权限恢复过来:

lion@node1:~$ chmod 400 .erlang.cookie

  最后分别在确认三台机器上的.erlang.cookie的值是一致的

lion@node1:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

lion@node2:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

lion@node3:~$ cat .erlang.cookie
VORMVSAAOFOFEQKTNWBA

2.三、使用detached参数,在后台启动Rabbit Node

  要先中止现有的Rabbitmq-server,再从新在后台支行

lion@node1:~$ rabbitmqctl stop
Stopping and halting node rabbit@node1 ...
Gracefully halting Erlang VM
lion@node1:~$ rabbitmq-server -detached

  经过rabbitmqctl cluster_status命令,能够查看和个节点的状态,节点的名称是rabbit@shorthostname,

node1:

lion@node1:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
[{nodes,[{disc,[rabbit@node1]}]},
 {running_nodes,[rabbit@node1]},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,[]},
 {alarms,[{rabbit@node1,[]}]}]

node2:

lion@node2:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node2 ...
[{nodes,[{disc,[rabbit@node2]}]},
 {running_nodes,[rabbit@node2]},
 {cluster_name,<<"rabbit@node2">>},
 {partitions,[]},
 {alarms,[{rabbit@node2,[]}]}]

node3:

lion@node3:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node3 ...
[{nodes,[{disc,[rabbit@node3]}]},
 {running_nodes,[rabbit@node3]},
 {cluster_name,<<"rabbit@node3">>},
 {partitions,[]},
 {alarms,[{rabbit@node3,[]}]}]

2.四、将node一、node二、node3组成集群

  由于rabbitmq-server启动时,会一块儿启动节点和应用,它预先设置RabbitMQ应用为standalone模式。要将一个节点加入到现有的集群中,你须要中止这个应用并将节点设置为原始状态,而后就为加入集群准备好了。若是使用./rabbitmqctl stop,应用和节点都将被关闭。因此使用rabbitmqctl stop_app仅仅关闭应用。

node2:

lion@node2:~$ rabbitmqctl stop_app
Stopping node rabbit@node2 ...
lion@node2:~$ rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node2 with rabbit@node1 ...
lion@node2:~$ rabbitmqctl start_app
Starting node rabbit@node2 ...

node3:

lion@node3:~$ rabbitmqctl stop_app
Stopping node rabbit@node3 ...
lion@node3:~$ rabbitmqctl join_cluster rabbit@node1
Clustering node rabbit@node3 with rabbit@node1 ...
lion@node3:~$ rabbitmqctl start_app
Starting node rabbit@node3 ...

  此时 node2 与 node3 也会自动创建链接。

  若是要使用内存节点,则可使用如下命令:

lion@node2:~$ rabbitmqctl join_cluster --ram rabbit@node1

  集群配置好后,能够在 RabbitMQ 任意节点上执行 rabbitmqctl cluster_status 来查看是否集群配置成功。

node1:

lion@node1:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node1 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
 {running_nodes,[rabbit@node1]},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,[]},
 {alarms,[{rabbit@node1,[]}]}]

node2:

lion@node2:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node2 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2]}]},{alarms,[{rabbit@node1,[]}]}]

node3:

lion@node3:~$ rabbitmqctl cluster_status
Cluster status of node rabbit@node3 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
 {alarms,[{rabbit@node1,[]}]}]

  同时在Web管理工具中也能够看到效果

 

2.五、RabbitMQ镜像功能

  使用Rabbit镜像功能,须要基于RabbitMQ策略来实现,策略是用来控制和修改群集范围的某个vhost队列行为和Exchange行为

lion@node2:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue"^" '{"ha-mode":"all"}'

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

  例以下面的命令,^message 这个规则要根据本身修改,这个是指同步"message"开头的队列名称,咱们配置时使用的应用于全部队列,因此表达式为"^"。

lion@node2:~$ rabbitmqctl set_policy -p hrsystem ha-allqueue "^message" '{"ha-mode":"all"}'

  更多set_policy说明:http://www.rabbitmq.com/man/rabbitmqctl.1.man.html

2.六、安装软件负载均衡器HAProxy1.6

  因为Ubuntu的快速发展,官方的源可能不是最新的版本,大多数时候安装多是1.4.24,能够经过如下命令,查询官方提供的版本号:

lion@node4:~$ sudo apt-cache showpkg haproxy

node4是一台新的机器 ,IP地址是192.168.0.34

  在写本文的时候,官方包是没有1.6版本的,咱们能够经过如下命令来安装 :

lion@node4:~$ sudo add-apt-repository ppa:vbernat/haproxy-1.6
lion@node4:~$ sudo apt-get update
lion@node4:~$ sudo apt-get install haproxy

  安装完之后,能够经过如下命令,查看安装的版本

lion@node4:~$ haproxy -v
HA-Proxy version 1.6.7 2016/07/13
Copyright 2000-2016 Willy Tarreau <willy@haproxy.org>

  安装完之后,配置文件的目录在/etc/haproxy/haproxy.cfg,如下是我修改后的配置文件

###########全局配置#########
global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy     # 改变当前工做目录
    stats socket /run/haproxy/admin.sock mode 660 level admin   # 建立监控所用的套接字目录
    pidfile  /var/run/haproxy.pid   # haproxy的pid存放路径,启动进程的用户必须有权限访问此文件 
    maxconn  4000                   # 最大链接数,默认4000
    user   haproxy                  # 默认用户
    group   haproxy                 # 默认用户组
    daemon                          # 建立1个进程进入deamon模式运行。此参数要求将运行模式设置为"daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

###########默认配置#########
defaults
    log global
    mode    http                                # 默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
    option  httplog                             # 采用http日志格式
    option  dontlognull                         # 启用该项,日志中将不会记录空链接。所谓空链接就是在上游的负载均衡器
                                                # 或者监控系统为了探测该 服务是否存活可用时,须要按期的链接或者获取某
                                                # 一固定的组件或页面,或者探测扫描端口是否在监听或开放等动做被称为空链接;
                                                # 官方文档中标注,若是该服务上游没有其余的负载均衡器的话,建议不要使用
                                                # 该参数,由于互联网上的恶意扫描或其余动做就不会被记录下来
    timeout connect 5000                    # 链接超时时间
    timeout client  50000                   # 客户端链接超时时间
    timeout server  50000                   # 服务器端链接超时时间
    option  httpclose       # 每次请求完毕后主动关闭http通道 
    option  httplog         # 日志类别http日志格式 
    #option  forwardfor      # 若是后端服务器须要得到客户端真实ip须要配置的参数,能够从Http Header中得到客户端ip  
    option  redispatch      # serverId对应的服务器挂掉后,强制定向到其余健康的服务器
    timeout connect 10000   # default 10 second timeout if a backend is not found
    maxconn     60000       # 最大链接数
    retries     3           # 3次链接失败就认为服务不可用,也能够经过后面设置 
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http
####################################################################
listen http_front
        bind 0.0.0.0:1080           #监听端口  
        stats refresh 30s           #统计页面自动刷新时间  
        stats uri /haproxy?stats            #统计页面url  
        stats realm Haproxy Manager #统计页面密码框上提示文本  
        stats auth admin:admin      #统计页面用户名和密码设置  
        #stats hide-version         #隐藏统计页面上HAProxy的版本信息

#####################我把RabbitMQ的管理界面也放在HAProxy后面了###############################
listen rabbitmq_admin 
    bind 0.0.0.0:8004
    server node1 192.168.0.31:15672
    server node2 192.168.0.32:15672
    server node3 192.168.0.33:15672
####################################################################
listen rabbitmq_cluster 
    bind 0.0.0.0:5672
    option tcplog
    mode tcp
    timeout client  3h
    timeout server  3h
    option          clitcpka
    balance roundrobin      #负载均衡算法(#banlance roundrobin 轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数)
    #balance url_param userid
    #balance url_param session_id check_post 64
    #balance hdr(User-Agent)
    #balance hdr(host)
    #balance hdr(Host) use_domain_only
    #balance rdp-cookie
    #balance leastconn
    #balance source //ip
    server   node1 192.168.0.31:5672 check inter 5s rise 2 fall 3   #check inter 2000 是检测心跳频率,rise 2是2次正确认为服务器可用,fall 3是3次失败认为服务器不可用
    server   node2 192.168.0.32:5672 check inter 5s rise 2 fall 3
    server   node3 192.168.0.33:5672 check inter 5s rise 2 fall 3

  更多Haproxy的配置文件介绍参考:http://www.haproxy.org/download/1.4/doc/configuration.txt

  从新启动HAProxy

lion@node4:~$ sudo service haproxy restart
 * Restarting haproxy haproxy                                                                                                 [ OK ]

  而后用浏览器输入http://:1080/haproxy?stats,能够看到如下结果,说明node一、node二、node3都已经搭建好了:

  

2.七、测试结果 ,向HAProxy发送消息

  使用Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践中的代码来发送消息, 在node3上咱们将消息发送到node4(192.168.0.34)上

原来默认的guest用户是禁止远程访问的,若是要使用lion账号访问,须要在web管理控制台中开启lion对Virtual Host访问

Console1(node3):

lion@node3:~/_code/_rabbitmq/_golang$ go run producer_hello.go
2016/07/29 12:46:50 dialing "amqp://lion:123456@192.168.0.34:5672/"
2016/07/29 12:46:50 got Connection, getting Channel
2016/07/29 12:46:50 got queue, declaring "test-idoall-queues"
2016/07/29 12:46:50 declared queue, publishing 16B body ("hello idoall.org")
2016/07/29 12:46:50 published 16B OK

Console(node1):

lion@node1:~/_code/_rabbitmq/_golang$ go run consumer_hello.go
2016/07/25 17:37:12 dialing "amqp://guest:guest@localhost:5672/"
2016/07/25 17:37:12 got Connection, getting Channel
2016/07/25 17:37:12 got queue, declaring "test-idoall-queues"
2016/07/25 17:37:12 Queue bound to Exchange, starting Consume
2016/07/25 17:37:12  [*] Waiting for messages. To exit press CTRL+C
2016/07/25 17:37:12 Received a message: hello idoall.org

  在上面的代码中,咱们能够看到在node3是向192.168.0.34这台HAProxy上发送消息,而后在node1上能够正常接收。

三、参考阅读

Haproxy 配置项\配置实例

How to Install HAProxy Load Balancer on Ubuntu

http://www.rabbitmq.com/clustering.html

Can't access RabbitMQ web management interface after fresh install

Nginx/LVS/HAProxy负载均衡软件的优缺点详解

相关文章
相关标签/搜索