RabbitMQ总结
基础知识
为什么要用消息队列
队列是一种先进先出的数据结构。
消息队列是分布式系统中重要的组件,
-
通过异步处理提高系统性能(削峰、减少响应所需时间)
在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。
-
降低系统耦合性
消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。
引入问题
- 系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了!
- 系统复杂性提高: 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!
- 一致性问题:万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了!
设计规范
由于消息队列的跨语言、跨平台的需求,发展出不同的规范
JMS
JMS(JAVA Message Service,java消息服务)是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。 ActiveMQ 就是基于 JMS 规范实现的。
- 点到点(P2P)模型: 一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。
- 发布/订阅(Pub/Sub)模型: 主题(Topic作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的。
AMQP
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。
- AMQP 为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。在 Java 体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。而AMQP天然具有跨平台、跨语言特性。
- JMS 支持TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)。
- 由于Exchange 提供的路由算法,AMQP可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种。
相关面试题
RabbitMQ队列六种工作模式
- 简单队列模式:最简单的工作队列,其中一个消息生产者,一个消息消费者,一个队列。也称为点对点模式
public class Producer {
/** 队列名称 */
private static final String QUEUE_NAME = "test_queue";
public static void main(String[] args) throws IOException, TimeoutException {
/** 1.获取连接 */
Connection newConnection = MQConnectionUtils.newConnection();
/** 2.创建通道 */
Channel channel = newConnection.createChannel();
/** 3.创建队列声明 */
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String msg = "我是生产者生成的消息";
System.out.println("生产者发送消息:" + msg);
/** 4.发送消息 */
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
channel.close();
newConnection.close();
}
}
工作模式:一个消息生产者,一个交换器,一个消息队列,多个消费者,多个消费者根据配置按序处理队列中的消息。同样也称为点对点模式,上面的消费者相关代码启动两次即可模拟。
发布订阅: 可以将一个消息发送给不同类型的消费者。消息通过交换机同时发送到不同队列,不同队列的消费者可以收到相同的消息。队列绑定同一个交换机,而不是消费者绑定一个队列。
-
路由模式: 路由模式跟发布订阅模式类似,然后在订阅模式的基础上加上了类型,订阅模式是分发到所有绑定到交换机的队列,路由模式只分发到绑定在交换机上面指定路由键的队列,我们可以看一下下面这张图:
-
主题模式: topics 主题模式跟 routing 路由模式类似,只不过路由模式是指定固定的路由键 routingKey,而主题模式是可以模糊匹配路由键 routingKey,类似于SQL中 = 和 like 的关系。
RPC模式:Client充当生产者,将请求发送到rabbitmq队列中,Server作为消费者,处理Client请求产生结果数据result,此刻Server作为生产者,将result通过rabbitmq队列传递到Client,Client作为结果数据的消费者,得到result
![img](https://upload-images.jianshu.io/upload_images/2758946-c015203772a97099.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)