第5章 RabbitMQ集群
在使用RabbitMQ的过程中,如果只有一个节点,但是一旦单机版宕机,服务不可用,影响比较严重,所以这里我们演示下如何搭建rabbitmq的集群,集群就能避免单点故障的问题。
RabbitMQ 集群分为两种 普通集群 和 镜像集群
5.1普通集群
以两个节点(rabbit01、rabbit02)为例来进行说明。
rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构,但消息实体只存在于其中一个节点rabbit01(或者rabbit02)中。
当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。
所以consumer应尽量连接每一个节点,从中取消息,即对于同一个逻辑队列,要在多个节点建立物理Queue;否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。
当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
5.2 镜像集群
在普通集群的基础上,把需要的队列做成镜像队列,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取,也就是说多少节点消息就会备份多少份。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用
由于镜像队列之间消息自动同步,且内部有选举master机制,即使master节点宕机也不会影响整个集群的使用,达到去中心化的目的,从而有效的防止消息丢失及服务不可用等问题。
5.3 集群搭建
准备两台虚拟机,虚拟机的地址分别为192.168.25.130, 192.168.25.134
设置192.168.25.130的别名为A:修改如下文件 名称改为A
vi /etc/hostname
设置192.168.25.134的别名为B,修改如下文件 名称改为B
vi /etc/hostname
修改每一个虚拟机的hosts
vi /etc/hosts
加入如下代码:
192.168.25.130 A
192.168.25.134 B
如下图所示:
重启系统。
5.3.1 安装erlang
192.168.25.130上安装如下:
输入命令,下载erlang:
wget http://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el6.x86_64.rpm
安装erlang,root用户使用rpm安装:
rpm -ihv erlang-18.1-1.el6.x86_64.rpm
5.3.2 下载和安装RabbitMQ
下载RabbitMQ:
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/rabbitmq_v3_6_12/rabbitmq-server-3.6.12-1.el6.noarch.rpm
安装RabbitMQ,
- 先安装socat
yum install -y socat
- root用户使用rpm安装 安装rabbitmq
rpm -ihv rabbitmq-server-3.6.12-1.el6.noarch.rpm
验证是否安装成功:
输入命令:
[root@A ~]# rabbitmq-server
出现如下界面,说明OK
守护进程启动方式:
rabbitmq-server -detached
其他相关指令:
启动服务:rabbitmq-server -detached
查看状态:rabbitmqctl status
关闭服务:rabbitmqctl stop
列出角色:rabbitmqctl list_users
改密码: rabbimqctlchange_password {username} {newpassword}
删除用户: rabbitmqctl delete_user xx
5.3.3配置RabbitMQ
(1)创建rabbitmq的账号
[root@A ~]# rabbitmqctl add_user admin admin
(2)将admin账号赋予管理员权限
[root@A ~]# rabbitmqctl set_user_tags admin administrator
(3)设置权限
[root@A ~]# rabbitmqctl set_permissions -p '/' admin '.*' '.*' '.*'
安装可视化界面
rabbitmq-plugins enable rabbitmq_management
5.4 配置rabbitmq集群
5.4.1 安装rabbitmq
安装方法如上边的方法进行在 192.168.25.134上进行
5.4.2 保证相同的erlang cookie
erlang.cookie是erlang分布式的token文件,集群内所有的设备要持有相同的.erlang.cookie文件才允许彼此通信。
scp /var/lib/rabbitmq/.erlang.cookie root@B:/var/lib/rabbitmq
[root@A rabbitmq]# scp /var/lib/rabbitmq/.erlang.cookie root@A:/var/lib/rabbitmq
The authenticity of host 'a (192.168.25.134)' can't be established.
ECDSA key fingerprint is cd:17:22:d1:10:81:d6:98:be:ad:cc:13:e0:0c:c3:03.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'a,192.168.25.134' (ECDSA) to the list of known hosts.
root@a's password:
.erlang.cookie 100% 20 0.0KB/s 00:00
[root@A rabbitmq]#
5.4.5 运行各个rabbitmq节点
先停止每一个服务器的服务
输入命令停止0
[root@A rabbitmq]# rabbitmqctl stop
再输入命令启动:
[root@A rabbitmq]# rabbitmq-server -detached
5.4.6 查看状态
[root@A rabbitmq]# rabbitmqctl cluster_status
5.4.7 将节点连接成集群
每一个服务器都关闭防火墙:
[root@B ~]# systemctl stop firewalld
B加入到集群A中,在B中执行如下命令:
[root@B ~]# rabbitmqctl stop_app
[root@B ~]# rabbitmqctl join_cluster rabbit@A
[root@B ~]# rabbitmqctl start_app
A不需要加入到自己
查看集群状态:在任意服务器上执行:
rabbitmqctl cluster_status
添加集群之前:
添加集群之后:
5.4.8 配置单web插件查看集群
在A服务器执行命令:
rabbitmq-plugins enable rabbitmq_management
在B服务器执行命令:
rabbitmq-plugins enable rabbitmq_management
在浏览器中输入A服务器的rabbitmq服务器地址:
http://192.168.25.130:15672
输入用户名和密码登录,如果登录失败,采取如下措施:
- 执行命令 设置guest为管理员
rabbitmqctl set_user_tags guest administrator
- 执行命令 设置权限
rabbitmqctl set_permissions -p / guest '.*' '.*' '.*'
- 在rabbitmq的配置文件目录下创建一个rabbitmq.config文件
cd /etc/rabbitmq
vi rabbitmq.config
输入如下文本,并保存:
[{rabbit, [{loopback_users, []}]}].
重新启动服务:
service rabbitmq-server restart
再次输入地址 出现界面,说明集群搭建成功。
如有需要,同理 对服务B的配置如上边一样配置一遍即可。
5.5 配置镜像队列
如上,我们已经搭建好了集群,但是并不能做到高可用,所以需要配置升级为镜像队列。
在任意的节点(A或者B)中执行如下命令:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
解释
rabbitmqctl set_policy
用于设置策略
ha-all
表示设置为镜像队列并策略为所有节点可用 ,意味着 队列会被(同步)到所有的节点,当一个节点被加入到集群中时,也会同步到新的节点中,此策略比较保守,性能相对低,对接使用半数原则方式设置(N/2+1),例如:有3个结点 此时可以设置为:ha-two 表示同步到2个结点即可。
"^" 表示针对的队列的名称的正则表达式,此处表示匹配所有的队列名称
'{"ha-mode":"all"}' 设置一组key/value的JSON 设置为高可用模式 匹配所有exchange
此时查看web管理界面:添加一个队列itcast111,如下图已经可以出现结果为有一个结点,并且是ha-all模式(镜像队列模式)
5.6 springboot整合rabbitmq集群使用(作业)
修改原来redis测试的项目,
(1)加入pom.xml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
(2)配置application.yml
spring:
rabbitmq:
addresses: 192.168.25.130:5672,192.168.25.134:5672
username: guest
password: guest
(3)创建controller
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findOne/{username}")
public TbUser findOne(@PathVariable String username) {
return userService.findOne(username);
}
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/send")
public String ok(){
rabbitTemplate.convertAndSend("itcast111","hello");
return "ok";
}
}
(4)设置监听:
代码:
@Component
@RabbitListener(queues = "itcast111")
public class Lisnter {
@RabbitHandler
public void getInfo(String message){
System.out.println("123131");
System.out.println(message);
}
}
测试,在浏览器中输入:
http://localhost:9008/user/send
测试当宕机一台rabbitmq也能发送成功。
如下效果。