公司要对常见的几种消息中间件进行选型,最后在ActiveMQ、RabbitMQ、RocketMQ中选择了RabbitMQ作为技术标准。本文对RabbitMQ的安装使用过程进行记录。
1、首先了解一下我们用消息中间件主要来解决的三类问题:
a、系统间的解耦:两个系统之间本来是直接调用的(强依赖),可以通过在中间加入消息中间件来解耦。
b、削峰(高并发):例如秒杀场景,上游订单系统效率很高(一瞬间生成了1万个订单),下游秒杀系统的业务逻辑比较复杂费时,可以在中间加入消息中间件,上游系统发送消息到mq,下游系统根据自己的处理能力定时到mq里取任务,使得整个系统健壮性增强。
c、异步:原来是同步顺序执行的过程集合(A->B->C),可以改成某些过程同时执行(A->B 与 A->C 同时执行),使得整个系统对外响应变快。
2、rabbitmq是使用erlang语言开发的,所以安装的时候要先装erlang环境,而且rabbitmq的不同版本对应不同的erlang版本,这点要特别注意,否则装了运行不起来,具体在rabbitmq官网可以查看版本对应关系。另外就是注意.erlang.cookie文件在c:\windows目录下最好得有,不然可能运行不起来。安装教程网上很多,例如:
https://blog.csdn.net/qq_36505948/article/details/82734133
安装完成后,可通过浏览器访问管理台地址 http://localhost:15672 使用用户名guest、密码guest登录查看。
注意:guest账号只能用于通过浏览器方式在本地登录,不能用于远程登录或者系统开发方式的建立connection。例如以下代码会出错:
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "172.16.170.75";
factory.UserName = "guest";
factory.Password = "guest";
using (IConnection conn = factory.CreateConnection()) --会出现身份验证错误
解决方案是在管理台中增加一个新的账号。
3、rabbitmq的交换中心(Exchange)可以对接多个消息队列(Queue),上游系统给Exchange发送消息,Exchange根据设置的匹配规则将消息转发到对应的Queue里。三种模式:Fanout模式下,直接转发消息到所有的Queue;Direct模式下,routingkey与bindingkey完全匹配,才会发送到对应的Queue;Topic模式下,routingkey与bindingkey,符合匹配规则时,才会发送到对应的Queue。想要简单直接使用Direct模式就好。
4、rabbitmq消息持久化存储,需要声明交换中心(Exchange)、消息队列(Queue)都为持久化模式(durable=true),否则万一消息服务挂了,消息就丢失了。
5、rabbitmq消息本地一般存放在C:\Users\Administrator\AppData\Roaming\RabbitMQ\db\rabbit@WIN-GJAQLSGL4BB-mnesia\msg_stores\vhosts目录下(windows环境,Administrator为windows当前登录用户账号,WIN-GJAQLSGL4BB为机器名称),*.rdq文件中,用于持久化。服务启动后,会从rdq文件中加载待发送消息到内存里。需要注意的是,如果文件资源管理器(文件窗口)打开了rabbitmq的这些目录,服务重启后,有可能会显示state=DOWN,不可用。怀疑是因为权限冲突,解决方案是关闭文件窗口后重启服务。
6、windows环境下的集群高可用配置
a、两台机器分别安装好erlang与rabbitmq;
b、分别修改两台机器的hosts文件,内容如下(两台机器内容一样):
172.16.170.75 rabbit@WIN-GJAQLSGL4BB
172.16.170.74 rabbit@WIN-GJAQLSGL4BA
c、分别增加两台机器的配置文件rabbitmq.config(C:\Users\Administrator\AppData\Roaming\RabbitMQ 目录下),内容如下(注意最后的点别少了。两台机器内容一样):
[{rabbit,[{cluster_nodes,['rabbit@WIN-GJAQLSGL4BA','rabbit@WIN-GJAQLSGL4BB']}]}].
d、分别增加两台机器的配置文件,内容如下(注意机器名与ip地址为本机的):
NODENAME=rabbit@WIN-GJAQLSGL4BB
NODE_IP_ADDRESS=172.16.170.75
NODE_PORT=5672
RABBITMQ_MNESIA_BASE=C:\Users\Administrator\AppData\Roaming\RabbitMQ\db
RABBITMQ_LOG_BASE=C:\Users\Administrator\AppData\Roaming\RabbitMQ\log
e、保证两台机器的.erlang.cookie文件一致(这个文件里的哈希值是用来验证集群通讯身份的):将一台机器的.erlang.cookie复制到另一台机器上(c:\Users\Administrator 以及 C:\Windows\System32\config\systemprofile 两个目录)
f、关闭防火墙!或者设置防火墙出入站规则(我第一次配置就是因为没有关闭防火墙导致出现莫名其妙的问题),否则后面的操作会失败。这几个端口号放开:4369, 5672, 15672, 25672
g、在rabbit@WIN-GJAQLSGL4BB机器的rabbitmq安装目录下(C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.5\sbin>)运行如下命令:
rabbitmqctl stop_app (关闭节点)
rabbitmqctl reset (重置配置)
rabbitmqctl start_app (重启节点)
h、在rabbit@WIN-GJAQLSGL4BA机器的rabbitmq安装目录下(C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.5\sbin>)运行如下命令:
rabbitmqctl stop_app (关闭节点)
rabbitmqctl reset (重置配置)
rabbitmqctl join_cluster rabbit@WIN-GJAQLSGL4BB (将另一台节点加入到集群里)
rabbitmqctl start_app (重启节点)
这个时候应该从管理台能看到节点变成2个了。如图:
i、在管理台的Admim —》policies中,增加一个策略,这里是匹配所有,意味着,不管消息生产者给哪个消息节点发送消息,消息都会在集群中的所有服务器节点内存储。高可用模式具体其他设置可百度查询。
j、OK,到这一步就可以进行破坏性测试了。把其中一台RabbitMQ服务器关机,消费者依然还可以从其他节点服务器获取消息。当服务器重启后,还未被消费的消息又会自动同步到这台机器上。