第一步:安装必要的环境
# yum install gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel xmlto unixODBC-devel -y
安装必要的环境
第二步:安装二郎语言
wget http://erlang.org/download/otp_src_19.2.tar.gz
下载二郎语言,这一步会很慢,但要等待
解压
tar -xzvf otp_src_19.2.tar.gz
创建安装目录
mkdir /usr/local/erlang
进入解压路径
cd otp_src_19.2
编译并安装
./configure —prefix=/usr/local/erlang —enable-smp-support —enable-threads —enable-sctp —enable-kernel-poll —enable-hipe —with-ssl —without-javac
安装
make && make install
修改环境变量
vim /etc/profile
#追加环境变量到文件末尾
export PATH=$PATH:/usr/local/erlang/bin
应用环境变量
source /etc/profile
测试erlang安装是否成功
# erlErlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false]Eshell V9.3 (abort with ^G) # 出现这个命令提示符说明 erlang 安装成功1>erlang:halt(). # 退出 erlang,注意 halt() 后面有个 点

  1. 另外一种安装erlang的方法:
  2. https://dl.bintray.com/rabbitmq-erlang/rpm/erlang/21/el/7/x86_64/
  3. 这个网站中,本地下载
  4. wget https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc #下载密钥
  5. rpm --import rabbitmq-release-signing-key.asc #导入rpm库的密钥
  6. rpm -ivh erlang-21.2.4-1.el7.centos.x86_64.rpm

erlang,rabbitmq,秘钥等,可在csdn资源中找到。
//download.csdn.net/download/smile_795/12133763
//download.csdn.net/download/smile_795/12133762
第三步:安装rabbitmq
下载路径
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-generic-unix-3.6.5.tar.xz
a. 解压二进制包,解压即可用# tar xvf rabbitmq-server-generic-unix-3.7.5.tar.xz -C /usr/local/

  1. rpm包安装
  2. yum install rabbitmq-server-3.7.9-1.el7.noarch.rpm

systemctl enable rabbitmq-server 开机启动
systemctl start rabbitmq-server
rabbitmq-server -detached 后台启动命令
rabbitmq-server stop 停止命令
到安装路径下
./rabbitmq-plugins enable rabbitmq_management 开启插件管理页面
./rabbitmq-server 直接启动
rabbitmqctl status 查看状态
rabbitmqctl list_users 列出角色

检测是否安装成功
rabbitmqctl status

创建目录
mkdir /etc/rabbitmq
然后才能启动plugins

添加用户 以及密码
rabbitmqctl add_user admin admin123
# 查看用户列表
rabbitmqctl list_users
# 添加进管理员,此处假如不添加管理员,在登陆的时候会报错,此用户不是管理员。所以必须添加。
rabbitmqctl set_user_tags admin administrator

开放端口:
firewall-cmd —permanent —add-port=15672/tcp
firewall-cmd —permanent —add-port=5672/tcp
systemctl restart firewalld.service

到这里你的rabbitmq就可以使用了
常见问题:
1、启动不了,有可能是已经启动过了,ps aux|grep rabbit 查看进程id kill -9 pid杀掉
2、安装失败可能是版本不对应,卸载删除干净,安装对应的版本
3、访问不了15672或者5672可能是端口未开放,开放端口,直接关闭防火墙,即可访问成功
============================================================================
四、群集配置
1、设置节点相互信任:Erlang Cookie
RabbitMQ 节点和 CLI 工具(例如 rabbitmqctl )使用 cookie 来确定它们是否被允许相互通信,要使两个节点能够通信,它们必须具有相同的共享密钥,称为 Erlang Cookie。 Cookie 只是一个字符串,最多可以有 255 个字符。它通常存储在本地文件中。 该文件必须只能由所有者访问(400 权限) 。每个集群节点必须具有相同的 cookie,文件位置(rpm 安装) /var/lib/rabbitmq/.erlang.cookie,如果是源码安装的 .erlang.cookie 文件在 启动用户的家目录中。把 rabbit2、rabbit3 设置成和 rabbit1 一样的即可,权限是 400 ,或者直接复制一份过去即可。

  1. 这里采用复制的方式
  2. 采用源码安装的 rabbitmq .erlang.cookie 文件在 /root 目录下
  3. # scp /var/lib/rabbitmq/.erlang.cookie node02:/root/
  4. root@node02's password:
  5. .erlang.cookie 100% 20 2.3KB/s 00:00
  6. # scp /var/lib/rabbitmq/.erlang.cookie node03:/root/
  7. root@node03's password:
  8. .erlang.cookie 100% 20 7.5KB/s 00:00

2、正常方式启动所有节点
# rabbitmq-server -detached # 在所有节点上启动 rabbitmq-server
3、查看群集状态

  1. # nod01
  2. # rabbitmqctl cluster_status
  3. Cluster status of node rabbit@node01 ...
  4. [{nodes,[{disc,[rabbit@node01]}]},
  5. {running_nodes,[rabbit@node01]},
  6. {cluster_name,<<"rabbit@node01">>},
  7. {partitions,[]},
  8. {alarms,[{rabbit@node01,[]}]}]
  9. # node02
  10. # ./rabbitmqctl cluster_status
  11. Cluster status of node rabbit@node02 ...
  12. [{nodes,[{disc,[rabbit@node02]}]},
  13. {running_nodes,[rabbit@node02]},
  14. {cluster_name,<<"rabbit@node02">>},
  15. {partitions,[]},
  16. {alarms,[{rabbit@node02,[]}]}]
  17. # node03
  18. # ./rabbitmqctl cluster_status
  19. Cluster status of node rabbit@node03 ...
  20. [{nodes,[{disc,[rabbit@node03]}]},
  21. {running_nodes,[rabbit@node03]},
  22. {cluster_name,<<"rabbit@node03">>},
  23. {partitions,[]},
  24. {alarms,[{rabbit@node03,[]}]}]

4、将 node02、node03 加入 rabbit@node01 群集

  1. a. 停止 node02 rabbitmq 应用程序
  2. # 在其余 2 个节点上操作
  3. # ./rabbitmqctl stop_app
  4. Stopping rabbit application on node rabbit@node02 ...
  5. b. 加入 rabbit@node01 群集1
  6. # 在其余 2 个节点上操作
  7. # ./rabbitmqctl join_cluster rabbit@node01 # 如果这一步报错的话,请在所有节点打开相应的端口,打开 4369 端口
  8. Clustering node rabbit@node02 with rabbit@node01
  9. c. 启动 rabbitMQ 程序
  10. # 在其余 2 个节点上操作
  11. # ./rabbitmqctl start_app
  12. Starting node rabbit@node02 ...
  13. completed with 3 plugins.
  14. b. 查看群集状态
  15. 在群集任何一个节点上都可以查看到群集的状态
  16. # rabbitmqctl cluster_status
  17. Cluster status of node rabbit@node01 ...
  18. [{nodes,[{disc,[rabbit@node01,rabbit@node02,rabbit@node03]}]},
  19. {running_nodes,[rabbit@node03,rabbit@node02,rabbit@node01]},
  20. {cluster_name,<<"rabbit@node01">>},
  21. {partitions,[]},
  22. {alarms,[{rabbit@node03,[]},{rabbit@node02,[]},{rabbit@node01,[]}]}]
  23. 通过上面的步骤,我们可以在群集运行的同时随时向群集添加新节点

已加入群集的节点可以随时停止,也可以崩溃。在这两种情况下,群集的其余部分都会继续运行,并且节点在再次启动时,会自动 ”跟上“(同步)其它群集节点。
注意:
当整个集群关闭时,最后一个关闭的节点必须是第一个启动的节点,如果不是这样,节点会等待 30s 等待最后的磁盘节点恢复状态,然后失败。如果最后下线的节点不能上线,可以使用 forget_cluster_node 命令将其从群集中删除。如果所有的节点不受控制的同时宕机,比如掉电,会进入所有的节点都会认为其他节点比自己宕机的要晚,即自己先宕机,这种情况下可以使用 force_boot 指令来启动一个节点。
d. 设置群集模式为”镜像队列”模式
# rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:”all”}’
五、群集移除节点
当节点不再是节点的一部分时,需要从群集中明确地删除节点。
将 rabbit@node02 从群集中删除,回到独立模式:

  1. rabbit@node02 上操作:
  2. 1、停止 RabbitMQ 应用程序。
  3. # ./rabbitmqctl stop_app
  4. Stopping rabbit application on node rabbit@node02 ...
  5. 2、重置节点。
  6. # ./rabbitmqctl reset
  7. Resetting node rabbit@node02 ...
  8. 3、重新启动 RabbitMQ 应用程序。
  9. # ./rabbitmqctl start_app
  10. Starting node rabbit@node02 ...
  11. completed with 3 plugins.
  12. 4、在节点上运行 cluster_status 命令,确认 rabbit@node02 现在已经不再是群集的一部分,并独立运行
  13. # ./rabbitmqctl cluster_status
  14. Cluster status of node rabbit@node02 ...
  15. [{nodes,[{disc,[rabbit@node02]}]},
  16. {running_nodes,[rabbit@node02]},
  17. {cluster_name,<<"rabbit@node02">>},
  18. {partitions,[]},
  19. {alarms,[{rabbit@node02,[]}]}]
  20. 也可以远程删除节点,例如,在处理无响应的节点时,这很有用。
  21. 例如,在节点 rabbit@node01 上把 rabbit@node03 从群集中移除
  22. 1、先在 rabbit@node03 上将 RabbitMQ 应用停掉
  23. # ./rabbitmqctl stop_app
  24. Stopping rabbit application on node rabbit@node03 ...
  25. 2、在 rabbit@node01 上远程将 rabbit@node03 删除
  26. # rabbitmqctl forget_cluster_node rabbit@node03
  27. Removing node rabbit@node03 from the cluster
  28. 3、请注意,这时,rabbit@node03 仍然认为它还在 rabbit@node01 的群集里面,并试图启动它,这将会导致错误。我们需要将 rabbit@node03 重新设置才能重新启动它。(在 rabbit@node03 上操作)
  29. # ./rabbitmqctl reset
  30. Resetting node rabbit@node03 ...
  31. 4、重新启动 rabbit@node03
  32. # ./rabbitmqctl start_app
  33. Starting node rabbit@node03 ...
  34. completed with 3 plugins.

现在,三个节点都是作为独立的节点在运行。
注意:此时,rabbit@node01 保留了簇的剩余状态,而 rabbit@node02 和 rabbit@node03 是刚刚初始化的 RabbitMQ。如果想重新初始化 rabbit@node01 的话,需要按照与其它节点相同的步骤进行即可:
1、停止 RabbitMQ 应用程序
2、 重置 RabbitMQ
3、启动 RabbitMQ 应用程序
六、RabbitMQ 管理
1、主机名更改
RabbitMQ 节点使用主机名相互通信。因此,所有节点名称必须能够解析所有群集对应的名称。像 rabbitmqctl 这样的 工具 也是如此。除此之外,默认情况下 RabbitMQ 使用系统的当前主机名来命名数据库目录。如果主机名更改,则会创建一个新的空数据库。为了避免数据丢失,建立一个固定和可解析的主机名至关重要。每当主机名更改时,应该重新启动 RabbitMQ。如果要使用节点名称的完整主机名(RabbitMQ 默认为短名称),并且可以使用 DNS 解析完整的主机名,则需要修改设置环境变量 RABBITMQ_USE_LONGNAME=true
2、RAM 节点的群集
RAM 节点只将其元数据保存在内存中。 只有 RAM 节点的集群是脆弱的, 如果群集停止,将无法再次启动, 并将丢失所有数据。
创建 RAM 节点
我们可以在首次加入集群时将节点声明为 RAM 节点。像之前一样,我们使用 rabbitmqctl join_cluster 来完成此 操作,但传递 —ram 标志

  1. [root@node03 escript]# ./rabbitmqctl stop_app
  2. Stopping rabbit application on node rabbit@node03 ...
  3. [root@node03 escript]# ./rabbitmqctl join_cluster --ram rabbit@node01
  4. Clustering node rabbit@node03 with rabbit@node01
  5. [root@node03 escript]# ./rabbitmqctl start_app
  6. Starting node rabbit@node03 ...
  7. completed with 3 plugins.
  8. [root@node03 escript]# ./rabbitmqctl cluster_status
  9. Cluster status of node rabbit@node03 ...
  10. [{nodes,[{disc,[rabbit@node01]},{ram,[rabbit@node03]}]},
  11. {running_nodes,[rabbit@node01,rabbit@node03]},
  12. {cluster_name,<<"rabbit@node01">>},
  13. {partitions,[]},
  14. {alarms,[{rabbit@node01,[]},{rabbit@node03,[]}]}]

更改节点类型
可以将节点的类型 RAM 更改为 disc,反之亦然。
使用 change_cluster_node_type 命令。

  1. [root@node03 escript]# ./rabbitmqctl stop_app
  2. Stopping rabbit application on node rabbit@node03 ...
  3. [root@node03 escript]# ./rabbitmqctl change_cluster_node_type disc
  4. Turning rabbit@node03 into a disc node
  5. [root@node03 escript]# ./rabbitmqctl start_app
  6. Starting node rabbit@node03 ...
  7. completed with 3 plugins.
  8. [root@node03 escript]# ./rabbitmqctl cluster_status
  9. Cluster status of node rabbit@node03 ...
  10. [{nodes,[{disc,[rabbit@node01,rabbit@node03]}]},
  11. {running_nodes,[rabbit@node01,rabbit@node03]},
  12. {cluster_name,<<"rabbit@node01">>},
  13. {partitions,[]},
  14. {alarms,[{rabbit@node01,[]},{rabbit@node03,[]}]}]

常用管理命令

  • 用户权限管理

RabbitMQ 有一个默认的用户’guest’,密码也是”guest”,这个用户默认只能通过本机访问,如: http://localhost:15672 ,在通过 http 访问之前记得启用 management 插件。
要让其他机器可以访问,需要创建一个新用户,并为其分配权限。

  1. 用户管理

rabbitmqctl list_users # 列出所有用户
rabbitmqctl add_user {username} {password} # 添加用户
rabbitmqctl delete_user {username} # 删除用户
rabbitmqctl change_password {username} {newpassword} # 修改密码
rabbitmqctl authenticate_user {username} {password} # 用户认证
rabbitmqctl clear_password {username} # 删除密码,密码删除后就不能访问了。
rabbitmqctl set_user_tags {username} {tag …} # 为用户设置角色,tag 可以是 0 个,一个,或多个。如: rabbitmqctl set_user_tags chris administrator ,设置为管理员; rabbitmqctl set_user_tags chris ,清除 chris 与角色的关联。

  1. 权限管理

RabbitMQ 客户端连接到一个服务端的时候,在它的操作指令中指定了一个虚拟主机。服务端首先检查是否有访问该虚拟主机的权限,没有权限的会拒绝连接。
对于 exchanges 和 queues 等资源,位于某个虚拟主机内;不同虚拟主机内即便名称相同也代表不同的资源。当特定操作在资源上执行时第二级访问控制开始生效。
RabbitMQ 在某个资源上区分了配置、写和读操作。配置操作创建或者销毁资源,或者更改资源的行为。写操作将消息注入进资源之中。读操作从资源中获取消息。
要执行特定操作用户必须授予合适的权限。
rabbitmqctl list_vhosts [vhost info item …] # 获取 vhosts 列表
rabbitmqctl add_vhost {vhost} # 添加 vhosts
rabbitmqctl delete_vhost {hosts} # 删除 vhosts
rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read} # 给用户分配对应的 vhost 上分配相应的权限。如: rabbitmqctl set_permissions -p /myvhost chris “^chris-.“ “.“ “.
rabbitmqctl clear_permissions [-p vhost] {username} # 清除权限
rabbitmqctl list_permissions [-p vhost] # 清除权限列表
rabbitmqctl list_user_permissions {username} # user 权限列表
rabbitmqctl set_permissions -p / chris “.
“ “.“ “.“ 此时用户chris才有访问队列资源的权限
七、优化
运行生产工作负载的 RabbitMQ 安装可能需要系统限制和内核参数调整,以便处理体面的并发连接和队列。需要调整的主要设置是打开文件的最大数量,也称为 ulimit -n 。建议在生产环境中为用户 rabbitmq 至少允许 65536个文件描述符。4096 对于大多数开发工作量来说应该是足够的。
有两个限制操作系统内核允许的最大打开文件数(fs.file-max)和每用户限制(ulimit -n)。前者必须高于后者
fs.file-max 设置,在 /etc/sysctl.conf 文件中添加:
fs.file-max = 65535 # sysctl -p
用户限制(ulimit -n)

  1. # vim /etc/security/limits.conf
  2. 在最后一行添加如下内容
  3. root soft nofile 65535
  4. root hard nofile 65535
  5. * soft nofile 65535
  6. * hard nofile 65535
  7. 重启系统后才能生效,如果想立即生效,可以先使用如下命令:
  8. # ulimit -SHn 65535

ulimit 命令详解
ulimit用于shell启动进程所占用的资源,是shell内建命令。
参数介绍:-H 设置硬件资源限制. -S 设置软件资源限制. -a 显示当前所有的资源限制. -c size:设置core文件的最大值.单位:blocks -d size:设置数据段的最大值.单位:kbytes -f size:设置创建文件的最大值.单位:blocks -l size:设置在内存中锁定进程的最大值.单位:kbytes -m size:设置可以使用的常驻内存的最大值.单位:kbytes -n size:设置内核可以同时打开的文件描述符的最大值.单位:n -p size:设置管道缓冲区的最大值.单位:kbytes -s size:设置堆栈的最大值.单位:kbytes -t size:设置CPU使用时间的最大上限.单位:seconds -v size:设置虚拟内存的最大值.单位:kbytesLinux
修改 rabbitmq 配置

  1. 如果是 RPM 包安装的 RabbitMQ,修改 /usr/lib/systemd/system/rabbitmq-server.service
  2. [Service] 中,增加 LimitNOFILE=30000(具体数值根据需要而定)
  3. 执行 systemctl daemon-reload
  4. 重启 rabbitmq 服务
  5. rabbitmqctl status 可以查看修改后的 limit 限制,如:
  6. {file_descriptors,
  7. [{total_limit,924},{total_used,2},{sockets_limit,829},{sockets_used,0}]},

日志
默认的情况下,日志位于 /var/log/rabbitmq 目录中(RPM 包安装的),源码安装的在 /usr/local/rabbitmq/var/log/rabbitmq 目录中,服务器的输出被发送到 RABBITMQ_NODENAME.log 文件。其它日志数据定入 RABBITMQ_NODENAME-sasl.log

八、高可用配置
image.png
利用haproxy做负载均衡 在192.168.1.1和192.168.1.2节点上 安装haproxy # yum install haproxy
vi /etc/haproxy/haproxy.cfg 之后添加:

  1. #---------------------------------------------------------------------
  2. # Example configuration for a possible web application. See the
  3. # full configuration options online.
  4. #
  5. # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
  6. #
  7. #---------------------------------------------------------------------
  8. #---------------------------------------------------------------------
  9. # Global settings
  10. #---------------------------------------------------------------------
  11. global
  12. # to have these messages end up in /var/log/haproxy.log you will
  13. # need to:
  14. #
  15. # 1) configure syslog to accept network log events. This is done
  16. # by adding the '-r' option to the SYSLOGD_OPTIONS in
  17. # /etc/sysconfig/syslog
  18. #
  19. # 2) configure local2 events to go to the /var/log/haproxy.log
  20. # file. A line like the following can be added to
  21. # /etc/sysconfig/syslog
  22. #
  23. # local2.* /var/log/haproxy.log
  24. #
  25. log 127.0.0.1 local2
  26. chroot /var/lib/haproxy
  27. pidfile /var/run/haproxy.pid
  28. maxconn 4000
  29. user haproxy
  30. group haproxy
  31. daemon
  32. # turn on stats unix socket
  33. stats socket /var/lib/haproxy/stats
  34. #---------------------------------------------------------------------
  35. # common defaults that all the 'listen' and 'backend' sections will
  36. # use if not designated in their block
  37. #---------------------------------------------------------------------
  38. defaults
  39. mode http
  40. log global
  41. option httplog
  42. option dontlognull
  43. option http-server-close
  44. option forwardfor except 127.0.0.0/8
  45. option redispatch
  46. retries 3
  47. timeout http-request 10s
  48. timeout queue 1m
  49. timeout connect 10s
  50. timeout client 1m
  51. timeout server 1m
  52. timeout http-keep-alive 10s
  53. timeout check 10s
  54. maxconn 3000
  55. #---------------------------------------------------------------------
  56. # main frontend which proxys to the backends
  57. #---------------------------------------------------------------------
  58. #frontend main *:5000
  59. # acl url_static path_beg -i /static /images /javascript /stylesheets
  60. # acl url_static path_end -i .jpg .gif .png .css .js
  61. # use_backend static if url_static
  62. # default_backend app
  63. #---------------------------------------------------------------------
  64. # static backend for serving up images, stylesheets and such
  65. #---------------------------------------------------------------------
  66. #backend static
  67. # balance roundrobin
  68. # server static 127.0.0.1:4331 check
  69. #---------------------------------------------------------------------
  70. # round robin balancing between the various backends
  71. #---------------------------------------------------------------------
  72. # backend app
  73. # balance roundrobin
  74. # server app1 127.0.0.1:5001 check
  75. # server app2 127.0.0.1:5002 check
  76. # server app3 127.0.0.1:5003 check
  77. # server app4 127.0.0.1:5004 check
  78. listen admin_stats
  79. bind 0.0.0.0:8100
  80. stats enable
  81. mode http
  82. log global
  83. stats uri /stats
  84. stats realm Haproxy\ Statistics
  85. stats auth admin:admin
  86. stats admin if TRUE
  87. stats refresh 30s
  88. listen rabbitmq_cluster
  89. bind 0.0.0.0:56720
  90. mode tcp
  91. option tcplog
  92. balance roundrobin
  93. server node05 192.168.2.75:5672 check inter 2000 rise 2 fall 3
  94. server node06 192.168.2.76:5672 check inter 2000 rise 2 fall 3
  95. listen rabbitmq_cluster_web
  96. bind 0.0.0.0:15673
  97. mode tcp
  98. option tcplog
  99. balance roundrobin
  100. server node05 192.168.2.75:15672 check inter 2000 rise 2 fall 3
  101. server node06 192.168.2.76:15672 check inter 2000 rise 2 fall 3
  102. keepalived 配置:
  103. ! Configuration File for keepalived
  104. global_defs {
  105. router_id node05
  106. vrrp_skip_check_adv_addr
  107. vrrp_strict
  108. vrrp_garp_interval 0
  109. vrrp_gna_interval 0
  110. }
  111. vrrp_script chk_haproxy {
  112. script "/opt/scripts/chk_haproxy.sh"
  113. interval 1
  114. weight -10
  115. }
  116. vrrp_instance HA {
  117. state MASTER # Keepalived 的角色。Master 表示主服务器,从 服务器 设置为 BACKUP
  118. interface ens33 # 指定监测网卡
  119. virtual_router_id 75 # 虚拟路由 ID,主备相同
  120. nopreempt
  121. priority 100 # 优先级,BACKUP 机器上的优先级要小于这个值
  122. advert_int 1 # 设置主备之间的检查时间,单位为s
  123. authentication { # 定义验证类型和密码
  124. auth_type PASS # 主备节点必须一致
  125. auth_pass 1111 # 主备节点必须一致
  126. }
  127. virtual_ipaddress {
  128. 192.168.2.100/32 dev ens33 lebel ens33:0
  129. }
  130. track_script {
  131. chk_haproxy
  132. }
  133. }