本片博客简单介绍rabbitmq单节点以及集群的配置安装,使用和rabbitmq的命令,和图形界面简单的介绍使用


话不多说直接进入正题,首先介绍下rabbitmq:

rabbitmq的历史:
RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco 、Redhat、iMatix 等联合制定了 AMQP 的公开标准。
RabbitMQ是由RabbitMQ Technologies Ltd开发并且提供商业支持的。该公司在2010年4月被SpringSource(VMWare的一个部门)收购。在2013年5月被并入Pivotal。其实VMWare,Pivotal和EMC本质上是一家的。不同的是VMWare是独立上市子公司,而Pivotal是整合了EMC的某些资源,现在并没有上市。
RabbitMQ的官网是http://www.rabbitmq.com

Rabbitmq是由LShift提供的一个Advanced Message Queuing Protocol(AMQP)的开源实现,由以高性能、健壮、以及可伸缩性出名的Erlang写成,因此也是继承了这些优点。

Rabbitmq两大组件:
Exchange 和 Queue (在 AMQP 1.0 里还会有变动),如下图所示,绿色的 X 就是 Exchange ,红色的是 Queue ,这两者都在 Server 端,又称作 Broker ,这部分是 RabbitMQ 实现的,而蓝色的则是客户端,通常有 Producer 和 Consumer 两种类型:

Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第1张图片

rabbitmq支持两种协议:

  • AMQP协议:默认
  • MQTT协议:需要手动开启(下面会介绍如何开启)

AMQP是什么:
高级消息队列协议使得遵从该规范的客户端应用和消息中间件服务器的全功能互操作成为可能。

AMQP范围:
为了完全实现消息中间件的互操作性,需要充分定义网络协议和消息代理服务的功能语义。
因此,AMQP定义网络协议和代理服务如下:
一套确定的消息交换功能,也就是“高级消息交换协议模型”。AMQP模型包括一套用于路由和存储消息的功能模块,以及一套在这些模块之间交换消息的规则。
一个网络线级协议(数据传输格式),客户端应用可以通过这个协议与消息代理和它实现的AMQP模型进行交互通信。
可以只实现AMQP协议规范中的的部分语义,但是我们相信明确的描述这些语义有助于理解这个协议


MQTT协议是什么:
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器(比如通过Twitter让房屋联网)的通信协议

MQTT协议特点:
为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
2、对负载内容屏蔽的消息传输;
3、使用 TCP/IP 提供网络连接;
4、有三种消息发布服务质量:

    “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
    “至少一次”,确保消息到达,但消息重复可能会发生。
    “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。

5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;

注:再使用rabbitmq的时候默认启用5672端口即AMQP协议,但是部分Android是使用不了AMQP协议的,所以我们要开启MQTT协议

RabbitMQ的使用场景:
RabbitMQ,或者说AMQP解决了什么问题,或者说它的应用场景是什么?
对于一个大型的软件系统来说,它会有很多的组件或者说模块或者说子系统或者(subsystem or Component or submodule)。那么这些模块的如何通信?这和传统的IPC有很大的区别。传统的IPC很多都是在单一系统上的,模块耦合性很大,不适合扩展(Scalability);如果使用socket那么不同的模块的确可以部署到不同的机器上,但是还是有很多问题需要解决。比如:
1)信息的发送者和接收者如何维持这个连接,如果一方的连接中断,这期间的数据如何方式丢失?
2)如何降低发送者和接收者的耦合度?
3)如何让Priority高的接收者先接到数据?
4)如何做到load balance?有效均衡接收者的负载?
5)如何有效的将数据发送到相关的接收者?也就是说将接收者subscribe 不同的数据,如何做有效的filter。
6)如何做到可扩展,甚至将这个通信模块发到cluster上?
7)如何保证接收者接收到了完整,正确的数据?
AMDQ协议解决了以上的问题,而RabbitMQ实现了AMQP。

系统框架:
在这里rabbitmq的工作原理我就不介绍了,大家想了解的可以去官网看下,这里给大家提供系统框架图:
Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第2张图片

RabbitMQ Server: 也叫broker server,它不是运送食物的卡车,而是一种传输服务。原话是RabbitMQ isn’t a food truck, it’s a delivery service. 他的角色就是维护一条从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输。但是这个保证也不是100%的保证,但是对于普通的应用来说这已经足够了。当然对于商业系统来说,可以再做一层数据一致性的guard(保护,防护装置),就可以彻底保证系统的一致性了。
Client A & B: 也叫Producer,数据的发送方。create messages and publish (send) them to a broker server (RabbitMQ).一个Message有两个部分:payload(有效载荷)和label(标签)。payload顾名思义就是传输的数据。label是exchange的名字或者说是一个tag,它描述了payload,而且RabbitMQ也是通过这个label来决定把这个Message发给哪个Consumer。AMQP仅仅描述了label,而RabbitMQ决定了如何使用这个label的规则。
Client 1,2,3:也叫Consumer,数据的接收方。Consumers attach to a broker server (RabbitMQ) and subscribe(订阅) to a queue。把queue比作是一个有名字的邮箱。当有Message到达某个邮箱后,RabbitMQ把它发送给它的某个订阅者即Consumer。当然可能会把同一个Message发送给很多的Consumer。在这个Message中,只有payload,label已经被删掉了。对于Consumer来说,它是不知道谁发送的这个信息的。就是协议本身不支持。但是当然了如果Producer发送的payload包含了Producer的信息就另当别论了。

Connection: 就是一个TCP的连接。Producer和Consumer都是通过TCP连接到RabbitMQ Server的。以后我们可以看到,程序的起始处就是建立这个TCP连接。
Channels: 虚拟连接。它建立在上述的TCP连接中。数据流动都是在Channel中进行的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel


介绍完rabbitmq的废话不多多说直接进入部署rabbitmq集群正题:

在这演示安装的是yum安装的,也建议搭建yum安装,否则erlang环境和rabbtmq的版本问题,可能部署会出问题

安装基本环境:

yum -y install wget vim bash-completion lrzsz nmap telnet tree net-tools bind-utils lsof ntpdate iotop

准备erlang环境:

wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

安装rabbitmq:

yum -y install erlang
yum -y install rabbitmq-server

erlang版本:erlang.x86_64 0:R16B-03.18.el7
rabbitmq版本:rabbitmq-server.noarch 0:3.3.5-34.el7

检查安装结果:

rpm -qa | grep rabbitmq

启动和查看状态:

systemctl status rabbitmq-server                #查看rabbitmq转态
systemctl start rabbitmq-server                  #启动rabbitmq
systemctl stop rabbitmq-server                  #关闭rabbitmq

rabbitmq很多情况下使用systemctl restart rabbitmq-server是没有效果的,必须要stop后在start

开启Web管理页面:

rabbitmq-plugins enable rabbitmq_management

开启MQTT协议:

rabbitmq-plugins enable rabbitmq_mqtt
AMQP协议端口默认:5672
Web页面默认端口:15672
MQTT协议默认端口:1883
默认登录用户名(admin权限):guest
默认登录密码:guest

如果想安装单节点到此就结束了,如果想安装集群的请继续往下走


首先讲解的是单机多节点部署rabbitmq集群:

首先按照上面的步骤安装个rabbitmq,在进行一下操作:

确定rabbitmq节点是关闭状态:
rabbitmqctl stop

方法一:

设置环境变量指定端口和节点名称:

RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit

后台启动节点:

rabbitmq-server -detached

重复上面的操作,但是端口和rabbitmq节点名不可一样:

RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit_01
rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbit_02
rabbitmq-server -detached

方法二:
通过编写主配置文件进行启动:(rabbitmq默认是没有主配置文件的)

vim /etc/rabbitmq/rabbitmq-env.conf
NODE_PORT=5672
NODENAME=rabbit
NODE_PORT=5673
NODENAME=rabbit_01
NODE_PORT=5674
NODENAME=rabbit_03
systemctl start rabbitmq-server

不论前面是采用哪种方式,但加入集群的方式一样的:
先听掉节点上的应用:

#停掉rabbit_01节点应用
rabbitmqctl -n@localhost rabbit_01 stop_app
#将rabbit_01添加到rabbit节点中
rabbitmqctl -n@localhost rabbit_01 join_cluster rabbit@localhost

#停掉rabbit_02节点应用
rabbitmqctl -n@localhost rabbit_02 stop_app
#将rabbit_02添加到rabbit节点中
rabbitmqctl -n@localhost rabbit_02 join_cluster rabbit@localhost

查看节点信息:

#注:此处只显示了集群中只有两个信息,如果按照上面操作添加,会显示三个节点信息
Cluster status of node rabbit@localhost ...
[{nodes,[{disc,[rabbit@localhost,rabbit_01@localhost]}]},
 {running_nodes,[rabbit@localhost]},
 {cluster_name,<<"rabbit@localhost">>},
 {partitions,[]},
 {alarms,[{rabbit@localhost,[]}]}]

这里将介绍多节点部署:

*注:多节点不同与单节点的情况,在多机环境,如果要在cluster集群内部署多个节点,需要注意两个方面:

  • 保证需要部署的这几个节点在同一个局域网内
  • 需要有相同的Erlang Cookie,否则不能进行通信,为保证cookie的完全一致,采用从一个节点copy的方式

正题:


IP 主机名 rabbitmq节点名
192.168.3.10 node1 rabbitmq1
192.168.3.100 node3 rabbitmq2
192.168.3.205 node4 rabbitmq3

都点尴尬,主机里面的hosts文件已经配好了,所以难得改了,就这么用把,但是你们看的时候要注意,我这里面没有node2


关闭防火墙,或者配置防火墙规则,否则后面加入集群会出现问题

  1. 配置node1主机hosts文件:(确保可以解析主机名)

    vim /etc/hosts
    192.168.3.10         node1
    192.168.3.100       node3
    192.168.3.205       node4
    scp /etc/hosts [email protected]:/etc/hosts
    scp /etc/hosts [email protected]:/etc/hosts
  2. 安装rabbitmq(三台上面同样操作):

    yum -y install wget vim bash-completion lrzsz nmap telnet tree net-tools bind-utils lsof ntpdate iotop
    wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    yum -y install erlang rabbitmq-server
  3. 配置相同的Erlang Cookie:
    确保三台的cookie一样,这样erlang就处在一个环境中
    首先要启动rabbitmq,否则没有cookie,并且cookie是隐藏文件:
    Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第3张图片
    注:三个接单都需要先启动rabbitmq,然后在关闭

  4. 在node1节点上执行:

    scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq
    scp /var/lib/rabbitmq/.erlang.cookie root@node4:/var/lib/rabbitmq
  5. 重启服务看看是否报错:

    *三个节点都重启看是否有报错*
    systemctl stop rabbitmq-server
    systemctl start rabbitmq-server

    注:要是有报错肯定是.erlang.cookie问题,要么把.erlang.cookie删了重新生成,要就看看是否是忘记关闭服务把cookie配置了,一定要注意这些细节性的东西

  6. 将节点加入集群
    #确保服务是启动的情况下进行
    node3节点上操作
    #将node3加入到node1节点集群中:
    rabbitmqctl stop_app                  #停掉节点服务
    rabbitmqctl reset                         #重置节点配置
    rabbitmqctl join_cluster rabbit@node1  
    # 将node3节点的rabbitmq加入到node1中
    # rabbitmqctl join_cluster rabbit@是固定格式写法
    rabbitmqctl start_app                  #启动节点

    Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第4张图片

我们接着讲node4也加入node1集群:
Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第5张图片

7.查看集群的状态:

rabbitmqctl cluster_status

Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第6张图片

注:从中我们可以看出这些几点都是disc(磁盘节点),我们可以手动把集群节点模式调成内存节点的,当然三台磁盘节点是最安全的,但是比较浪费资源,正常我们调整为两台磁盘一台内存即可


下面将介绍下如何设置集群的节点模式:
ram:内存
disc:磁盘
默认节点加入集群都是disc节点,设置ram节点两种方式:
方法一:
加入集群时设置type:

rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@node1
rabbitmqctl start_app

方法二:
加入集群后,修改disc节点为ram节点:

rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type ram
rabbitmqctl start_app

我使用了第二种方法将node4从磁盘节点改为内存节点:
Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第7张图片

我们总在命令行里面操作有时候很难受,所以我们开启Web点点点模式:(三台相同操作)

rabbitmq-plugins enable rabbitmq_management
systemctl stop rabbitmq-server
systemctl start rabbitmq-server

查看端口是否起来了,默认端口15672:
Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析


#三台相同操作
手动开启MQTT协议(1883端口),默认只开启AMQP协议(5672端口)

rabbitmq-plugins enable rabbitmq_mqtt
systemctl stop rabbitmq-server
systemctl start rabbitmq-server

查看端口状态:

Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第8张图片


集群创建用户
#只要在一个节点创建即可,都在一个集群中其他前节点都会有这个用户

rabbitmqctl add_user hcb hcb@pwd                #创建用户设置密码
rabbitmqctl set_permissions hcb ".*" ".*" ".*"    #给hcb赋权
rabbitmqctl set_user_tags hcb administrator   #给hcb赋予admin
systemctl restart rabbitmq-server                     #重启服务

此时我们到web页面中就可以用这个用户密码登录了

http://192.168.3.10:15672

Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第9张图片
#用默认用户guest登录也行,默认也是admin权限

登录后我们能看到集群的所有信息:
Centos7搭建RabbitMQ集群及单机多节点部署和rabbitmq理论解析_第10张图片

在此web如何用我就不多说了都是点点点特别简单,如果有不会的可以联系我,现场远程教学


RabbitMQ负载均衡
选择开源的HAproxy为rabbitmq集群做负载

安装epel:

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

安装HA:

yum -y install haproxy

配置HA:

cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vim /etc/haproxy/haproxy.cfg

先说下haproxy的配置文件意思:

global           #全局设置
       log 127.0.0.1   local0      #日志输出配置,所有日志都记录在本机,通过local0输出
       #log loghost    local0 info
       maxconn 4096             #最大连接数
       chroot /usr/local/haproxy
       uid 99                   #所属运行的用户uid
       gid 99                   #所属运行的用户组
       daemon                   #以后台形式运行haproxy
       nbproc 2                 #启动2个haproxy实例
       pidfile /usr/local/haproxy/haproxy.pid  #将所有进程写入pid文件
       #debug
       #quiet

defaults             #默认设置
       #log    global
       log     127.0.0.1       local3         #日志文件的输出定向
       mode    http         #所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
       option  httplog       #日志类别,采用httplog
       option  dontlognull  
       option  forwardfor   #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
       option  httpclose    #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现
       retries 3           #3次连接失败就认为服务器不可用,主要通过后面的check检查
       option  redispatch   #当serverid对应的服务器挂掉后,强制定向到其他健康服务器
       maxconn 2000                     #最大连接数
       stats   uri     /haproxy-admin  #haproxy 监控页面的访问地址
       contimeout      5000            #连接超时时间
       clitimeout      50000           #客户端连接超时时间
       srvtimeout      50000           #服务器端连接超时时间
       stats auth  Frank:Frank   #设置监控页面的用户和密码:Frank
stats hide-version         #隐藏统计页面的HAproxy版本信息

listen rabbitmq_local_cluster VIP:5670 //前段IP,供product和consumer来进行选择,由于5672端口已经默认使用,这里选择5670端口
     mode tcp   //负载均衡选项
     balance roundrobin //轮询算法将负载发给后台服务器
     server rabbit 192.168.3.10:5672 check inter 5000 rise 2 fall 3//负载均衡中的集群节点配置,这里选择的rabbit节点
     server rabbit 192.168.3.100:5672 check inter 5000 rise 2 fall 3
 server rabbit 192.168.3.205:5672 check inter 5000 rise 2 fall 3

  listen private_monitoring :8100
     mode http
     option httplog
     stats enable
     stats uri       /stats
     stats refresh 60s

#实际配置如:

global
    log 127.0.0.1 local0 info
    maxconn 4096
    stats socket /tmp/haproxy.socket uid haproxy mode 770 level admin
    daemon
defaults
    log global
    mode    tcp
    option  tcplog
    option  dontlognull
    retries 3
    option  redispatch
    maxconn 2000
    timeout connect 5s
    timeout client 120s
    timeout server 120s
listen rabbitmq_local_cluster 0.0.0.0:5670
    mode tcp
    balance roundrobin
    server cacheclod1 192.168.3.10:5672 check inter 5000 rise 2 fall 3
    server cacheclod2 192.168.3.100:5672 check inter 5000 rise 2 fall 3
    server cacheclod3 192.168.3.205:5672 check inter 5000 rise 2 fall 3
listen private_monitoring :8100
    mode http
    option httplog
    stats enable
    stats uri   /stats
    stats refresh 5s

启动HAproxy:

systemctl start haproxy

查看haproxy控制界面:

http://192.168.3.10:8100/stats

有志者事竟成,破釜沉舟,百二秦关终属楚;
苦心人天不负,卧薪尝胆,三千越甲可吞吴;

至此rabbitmq介绍完毕,还有好多东西没有说,比如集群的两种模式(镜像模式,普通模式),rabbitmq的配置文件啊,路由机制啊,这些在后面文档中将会为大家逐一讲解,对本片博客有不理解或者发现错误的地方欢迎联系一起探讨研究:QQ:1715721936