https://github.com/rabbitmq/erlang-rpm 这个网页上写的很清楚,安装rabbitmq 之前的erlang的安装方式
https://github.com/rabbitmq/rabbitmq-server/releases 想要什么版本,已及最低的erlang版本要求
http://www.rabbitmq.com/which-erlang.html 对应的版本关系
yum安装方法(安装最新版本)
一、首先安装erlang环境
cat > /etc/yum.repos.d/erlang.repo <<EOF
[rabbitmq_erlang]
name=rabbitmq_erlang
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/x86_64
gpgcheck=0
enabled=1
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
EOF
yum -y install erlang
二、安装rabbitmq-server
cat > /etc/yum.repos.d/rabbitmq.repo <<EOF
[bintray-rabbitmq-server]
name=bintray-rabbitmq-rpm
baseurl=https://dl.bintray.com/rabbitmq/rpm/rabbitmq-server/v3.8.x/el/7/
gpgcheck=0
enabled=1
EOF
yum -y install rabbitmq-server
三、起服务、开启管理界面、建用户(自带的guest guest只能本地登陆)
systemctl start rabbitmq-server
systemctl enable rabbitmq-server
rabbitmq-plugins enable rabbitmq_management
rabbitmqctl -help 可获得全面的帮助
rabbitmqctl add_user admin 123456
用户名 密码
rabbitmqctl set_user_tags admin administrator
用户 身份标签
四、登陆
ip:15672
也可以下载指定版本源码安装
安装准备
yum -y install make gcc gcc-c++ kernel-devel m4ncurses-devel openssl-devel unixODBC-devel
erlang官网地址: http://www.erlang.org/downloads
./configure --prefix=/usr/local/erlang --without-javac
./configure --prefix=/usr/local/erlang --enable-smp-support --enable-threads --enable-sctp --enable-kernel-poll --enable-hipe --with-ssl --without-javac
装完erlang设置环境变量
export PATH=$PAHT:/目录/bin
source /etc/profile
下载rabbitmq压缩包,并在yum仓库配新的erlangyum源,不然即使安装了新的也会检测不通过
cat /lib/systemd/system/rabbitmq-server.service <<<EOF
[Unit]
Description=RabbitMQ broker
After=syslog.target network.target
[Service]
Type=notify
User=rabbitmq
Group=rabbitmq
UMask=0027
NotifyAccess=all
TimeoutStartSec=3600
/etc/systemd/system/rabbitmq-server.service.d/limits.conf
LimitNOFILE=65536
LimitNOFILE=32768
Restart=on-failure
RestartSec=10
WorkingDirectory=/var/lib/rabbitmq
ExecStart=/usr/sbin/rabbitmq-server
ExecStop=/usr/sbin/rabbitmqctl shutdown
See rabbitmq/rabbitmq-server-release#51
SuccessExitStatus=69
[Install]
WantedBy=multi-user.target
EOF
RabbitMq
当Binding key与Routing Key相匹配时,消息将会被路由到对应的Queue中。
在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的Binding key。
Binding key并不是在所有情况下都生效,它依赖于Exchange Type,比如fanout类型的Exchange就会无视Binding key,而是将消息路由到所有绑定到该Exchange的Queue。
Procuder Publish的Message进入了Exchange。接着通过"routing keys”, RabbitMQ会找到应该把这个Message放到哪个queue里。queue也是通过这个routing keys来做的绑定。
Exchange Types
RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种
fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。
direct类型的Exchange路由规则也很简单,它会把消息路由到那些Binding key与Routing key完全匹配的Queue中。
topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到Binding Key与Routing Key相匹配的Queue中,但这里的匹配规则有些不同,它约定:
Routing Key为一个句点号“.”分隔的字符串(我们将被句点号". “分隔开的每一段独立的字符串称为一个单词),如"stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”。Binding Key与Routing Key一样也是句点号“. ”分隔的字符串。
Binding Key中可以存在两种特殊字符"“与”#",用于做模糊匹配,其中"“用于匹配一个单词,”#"用于匹配多个单词(可以是零个)。
headers类型的Exchange不依赖于Routing Key与Binding Key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对。如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。
ACK
如果一个Queue没被任何的Consumer Subscribe(订阅),当有数据到达时,这个数据会被cache,不会被丢弃。当有Consumer时,这个数据会被立即发送到这个Consumer。这个数据被Consumer正确收到时,这个数据就被从Queue中删除。
那么什么是正确收到呢?通过ACK。每个Message都要被acknowledged(确认,ACK)。我们可以显示的在程序中去ACK,也可以自动的ACK。如果有数据没有被ACK,那么RabbitMQ Server会把这个信息发送到下一个Consumer。
如果这个APP有bug,忘记了ACK,那么RabbitMQ Server不会再发送数据给它,因为Server认为这个Consumer处理能力有限。而且ACK的机制可以起到限流的作用(Benefitto throttling):在Consumer处理完成数据后发送ACK,甚至在额外的延时后发送ACK,将有效的balance Consumer的load。
Broker: 简单来说就是消息队列服务器实体
Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
VHost: 虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
Producer: 消息生产者,就是投递消息的程序
Consumer: 消息消费者,就是接受消息的程序
Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务
由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。
RabbitMq的三种模式
单一模式:即单机情况不做集群,就单独运行一个rabbitmq而已。
集群模式分两种
普通模式:默认模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
镜像模式:把需要的队列做成镜像队列,存在与多个节点属于RabbitMQ的HA方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
普通模式搭建
每个节点搭好后
1添加vhosts
x.x.x.x node1
x.x.x.x node2
2/var/lib/rabbitmq/.erlang.cookie 保持一致,是个隐藏文件
其他节点执行 rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@node1 --ram (默认disk)(rabbit是固定的)
rabbitmqctl start_app
也可以不–ram后面改
rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type ram
rabbitmqctl start_app
成为集群后需重新创建管理员
镜像模式
在任意节点设置policy
ha-mode:策略键
ha-sync-mode:automatic
1.all 队列镜像在集群中的所有节点上。当新节点添加到集群时,队列将镜像到该节点
2.exactly 集群中的队列实例数。
3.nodes 队列镜像到节点名称中列出的节点。
rabbitmqctl set_policy myha “^” ‘{“ha-mode”:“all”}’ 可以加–vhost vhost的名称
建的policy的名字 匹配规则(正则,^表所有)
启动顺序:磁盘节点 => 内存节点 关闭顺序:内存节点 => 磁盘节点 最后关闭必须是磁盘节点,不然可能回造成集群启动失败、数据丢失等异常情况。
如果关闭了集群中的所有节点,必须保证最后关闭的节点第一个启动,如,我按照先后顺序关闭了node-1、node-2、node-3 也就是node-3是最后一个关闭的。那么在启动是先启动node-3节点,node-1和node-2谁先启动都可以
否则机会启动失败(10次30秒的等待时间)
如果最后一个关闭的节点最终由于某些异常而无法启动,则可以通过 rabbitrnqctl forget_cluster_node 命令来将此节点剔出当前集群。如果集 群中的所有节点由于某些非正常因素,比如断电而关闭,那么集群中的节点都会认为还有其他 节点在它后面关闭,
此时需要调用 rabbitrnqctl force_boot 命令来启动一个节点,之后 集群才能正常启动。
- 场景1:A先停,B后停。
该场景下B是master,只要先启动B,再启动A即可。或者先启动A,再在30秒之内启动B即可恢复镜像队列。 - 场景2: A, B同时停。
该场景可能是由掉电等原因造成,只需在30秒之内连续启动A和B即可恢复镜像队列。 - 场景3:A先停,B后停,且A无法恢复。
该场景是场景1的加强版,因为B是master,所以等B起来后,在B节点上调用rabbitmqctl forget_cluster_node A,解除与A的cluster关系,再将新的slave节点加入B即可重新恢复镜像队列。 - 场景4:A先停,B后停,且B无法恢复。
该场景是场景3的加强版,比较难处理,早在3.1.x时代之前貌似都没什么好的解决方法,可能是我不知道,但是现在已经有解决方法了,在3.4.2 版本亲测有效。因为B是master,所以直接启动A是不行的,当A无法启动时,也就没办法在A节点上调用rabbitmqctl forget_cluster_node B了。新版本中,forget_cluster_node支 持–offline参数,offline参数允许rabbitmqctl在离线节点上执行forget_cluster_node命令,迫使 RabbitMQ在未启动的slave节点中选择一个作为master。当在A节点执行rabbitmqctl forget_cluster_node –offline B时,RabbitMQ会mock一个节点代表A,执行forget_cluster_node命令将B剔出cluster,然后A就能正常启动了。最后 将新的slave节点加入A即可重新恢复镜像队列。 - 场景5: A先停,B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件。
该场景是场景4的加强版,更加难处理。将A或B的数据库文件(默认在$RABBIT_HOME/var/lib目录中)拷贝至新节点C的目录下,再 将C的hostname改成A或B的hostname。如果拷过来的是A节点磁盘文件,按场景4处理方式;如果拷过来的是B节点磁盘文件,按场景3处理方 式。最后将新的slave节点加入C即可重新恢复镜像队列。