内容导读
- RabbitMq简介
- 安装准备
- RabbitMQ安装与配置
- 安装过程中的出错解决
- RabbitMQ云端配置参考
一、RabbitMQ简介
1.1 消息队列MQ简介
消息队列中间件是微服务分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性。
常用的消息队列:ActiveMQ(安全),RabbitMQ(高效),RocketMQ,Kafka(大数据中应用广泛)。
1.2 什么是RabbitMQ
RabbitMQ是一个由Erlang语言开发的基于AMQP协议的开源中间件。
RabbitMQ最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
AMQP:Advanced Message Queue高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。
RabbitMQ具体特点包括:
(1)可靠性(Reliability)
RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
(2)灵活的路由(Flexible Routing)
在消息进入队列之前,通过Exchange 来路由消息的。对于典型的路由功能,RabbitMQ已经提供了一些内置的 Exchange 来实现。
针对更复杂的路由功能,可以将多个Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。
(3)消息集群(Clustering)
多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker。
(4)高可用(Highly Available Queues)
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
(5)多种协议(Multi-protocol)
RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等。
(6)多语言客户端(Many Clients)
RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等。
(7)管理界面(Management UI)
RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。
(8)跟踪机制(Tracing)
如果消息异常,RabbitMQ提供了消息跟踪机制,使用者可以找出发生了什么。
(9)插件机制(Plugin System)
RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
二、安装准备
1.下载Eralng20.0,用于支持RabbitMQ的运行与编程
Downloads - Erlang/OTP
2.下载rabbitmq-server-3.7.4
Installing RabbitMQ | RabbitMQ
三、RabbitMQ安装与配置
1、安装erlang并配置环境
1.1 双击安装文件otp_win64_20.2.exe,点击next
1.2 选择安装目录d:\programd\erl9.2\,继续点next
1.3 配置环境变量
新建系统变量名为:ERLANG_HOME 变量值为erlang安装地址
双击系统变量path,点击“新建”,将%ERLANG_HOME%\bin加入到path中。
1.4 验证erlang是否安装成功
win+R键,输入cmd,再输入erl,看到erlang版本号就说明erlang安装成功了。
2、安装RabbitMQ
2.1 双击下载后的执行文件,安装过程与安装Erlang相同
2.2 安装RabbitMQ-Plugins插件
打开命令窗口,并进入RabbitMQ的sbin文件夹。
输入以下命令:rabbitmq-plugins enable rabbitmq_management,效果如下
2.3 验证rabbitmq是否安装成功
RabbitMQ的sbin文件夹下输入命令:rabbitmqctl status
出现下图,说明安装成功,同时说明RabbitMQ Server已经正常启动。
2.4 打开浏览器,地址栏输入mq访问地址http://127.0.0.1:15672,即可看到管理界面的登陆页
输入用户名和密码,都是guest,进入主界面
2.5 RabbitMQ管理界面
上边导航条依次是:概览、连接、信道、交换器、队列、用户管理
四、安装过程中的出错解决
1、出现 Authentication failed (rejected by the remote node), please check the Erlang cookie
解决办法:
清除cookie缓存,重启一下电脑,获取最新修改的cookie,即可解决该问题。
2、报错:Status of node rabbit@ … ** (ArgumentError) argument error (stdlib)
解决办法:
检查rabbitmq 服务的日志db、log 等文件夹的路径是否含有中文,检查本机的用户名是否为中文,如果存在中文会出现下面的报错。
将本机名称改为英文名称。
3、主机名原来为中文,改为英文后执行rabbitmqctl status报错, * connected to epmd (port 4369) on DESKTOP-AJ0N…suggestion: start the node
报错信息如下:
epmd reports: node ‘rabbit’ not running at all
no other nodes on DESKTOP-AJ0N
suggestion: start the node
解决办法:
执行以下命令,重新安装rabbit-mq
rabbitmq-service remove
rabbitmq-service install
如果上述命令还不行,则执行
rabbitmq-server start
4、报错"start_error, failed_to_start_child", 原因是rabbitmq和erlang版本不一致
解决办法:rabbitmq和erlang版本对应关系参考以下官网
https://www.rabbitmq.com/which-erlang.html
5、出现如下错误提示
Distribution failed: {{:shutdown, {:failed_to_start_child, :net_kernel, {:EXIT, :nodistribution}}}, {:child, :undefined, :net_sup_dynamic, {:erl_distribution, :start_link, [[:rabbitmqcli67, :shortnames], false]}, :permanent, 1000, :supervisor, [:erl_distribution]}}
解决办法:
检查rabbitmq服务的日志db、log等文件夹的路径是否含有中文,检查本机的用户名是否为中文,存在中文会出错。
请将本机名称,rabbitmq的日志 db、log等文件夹都改为英文。
五、RabbitMQ云端配置参考
云服务器需要在控制台添加“安全组设置”
1、阿里云配置
2、华为云配置
六、RabbitMQ在Spring boot中的应用
SpringBoot应用可以完成自动配置及依赖注入,可以通过Spring直接提供与MQ的连接对象。
6.1 消息生产者
- 创建SpringBoot应用,添加依赖
- 配置application.yml
server:
port: 9001
spring:
application:
name: producer
rabbitmq:
host: 47.96.11.185
port: 5672
virtual-host: host1
username: ytao
password: admin123
- 发送消息
@Service
public class TestService {
@Resource
private AmqpTemplate amqpTemplate;
public void sendMsg(String msg){
//1. 发送消息到队列
amqpTemplate.convertAndSend("queue1",msg);
//2. 发送消息到交换机(订阅交换机)
amqpTemplate.convertAndSend("ex1","",msg);
//3. 发送消息到交换机(路由交换机)
amqpTemplate.convertAndSend("ex2","a",msg);
}
}
6.2 消息消费者
- 创建项目添加依赖
- 配置yml
- 接收消息
@Service
//@RabbitListener(queues = {"queue1","queue2"})
@RabbitListener(queues = "queue1")
public class ReceiveMsgService {
@RabbitHandler
public void receiveMsg(String msg){
System.out.println("接收MSG:"+msg);
}
}
6.3 使用RabbitMQ传递对象
RabbitMQ是消息队列,发送和接收的都是字符串/字节数组类型的消息。
1、使用序列化对象
要求:
(1)传递的对象实现序列化接口
(2)传递的对象的包名、类名、属性名必须一致
- 消息提供者
@Service
public class MQService {
@Resource
private AmqpTemplate amqpTemplate;
public void sendGoodsToMq(Goods goods){
//消息队列可以发送 字符串、字节数组、序列化对象
amqpTemplate.convertAndSend("","queue1",goods);
}
}
//消息消费者
@Component
@RabbitListener(queues = "queue1")
public class ReceiveService {
@RabbitHandler
public void receiveMsg(Goods goods){
System.out.println("Goods---"+goods);
}
}
2、使用序列化字节数组
要求:
- 传递的对象实现序列化接口
- 传递的对象的包名、类名、属性名必须一致
- 消息提供者
@Service
public class MQService {
@Resource
private AmqpTemplate amqpTemplate;
public void sendGoodsToMq(Goods goods){
//消息队列可以发送 字符串、字节数组、序列化对象
byte[] bytes = SerializationUtils.serialize(goods);
amqpTemplate.convertAndSend("","queue1",bytes);
}
}
- 消息消费者
@Component
@RabbitListener(queues = "queue1")
public class ReceiveService {
@RabbitHandler
public void receiveMsg(byte[] bs){
Goods goods = (Goods) SerializationUtils.deserialize(bs);
System.out.println("byte[]---"+goods);
}
}
3、使用JSON字符串传递
要求:对象的属性名一直
- 消息提供者
@Service
public class MQService {
@Resource
private AmqpTemplate amqpTemplate;
public void sendGoodsToMq(Goods goods) throws JsonProcessingException {
//消息队列可以发送 字符串、字节数组、序列化对象
ObjectMapper objectMapper = new ObjectMapper();
String msg = objectMapper.writeValueAsString(goods);
amqpTemplate.convertAndSend("","queue1",msg);
}
}
- 消息消费者
@Component
@RabbitListener(queues = "queue1")
public class ReceiveService {
@RabbitHandler
public void receiveMsg(String msg) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Goods goods = objectMapper.readValue(msg,Goods.class);
System.out.println("String---"+msg);
}
}
更多精彩内容请关注本站!!!
版权归原作者 天涯幺妹 所有, 如有侵权,请联系我们删除。