一 、什么是消息队列?
消息队列主要用于应用解耦,流量削锋,异步消息等,实现高性能,高可用,可伸缩和最终一致性架构。可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。目前使用较多的消息队列有ActiveMQ,RabbitMQ,Kafka,RocketMQ等。
1. 应用解耦
在软件工程中,降低耦合度即可以理解为解耦,模块间有依赖关系必然存在耦合,理论上的绝对零耦合是做不到的,但可以通过一些现有的方法将耦合度降至最低。
举例:购物商城,用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统直接调用库存系统的接口。假如库存系统无法访问,则库存减订单将失败,从而导致订单失败,订单系统与库存系统耦合。所以采用消息队列作为中间件将库存系统与订单系统分离。
- 订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
- 库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
2. 流量削峰
削峰从本质上来说就是更多地延缓用户请求,以及层层过滤用户的访问需求,遵从“最后落地到数据库的请求数要尽量少”的原则。一般在秒杀或抢购活动中使用广泛。
举例:秒杀活动,一般会因为流量过大导致系统瘫痪。为解决这个问题,一般需要在用户与应用之间加入消息队列,使得用户请求先到达消息队列进行排队。假如消息队列长度超过最大数量,则直接抛弃用户请求或者进行后续处理。
3. 异步消息
两个通信应用之间可以不用同时在线等待,任何一方只需各自处理自己的业务,比如:发送方发送消息以后不用登录接收方的响应,可以接着处理其他的任务。
二、JMS && AMQP
1. JMS
(1)介绍
JMS(Java Message Service,Java消息服务)是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。JMS是一个与具体平台无关的API。它使分布式通信耦合度更低,消息服务更加可靠以及异步消息处理。ActiveMQ就是基于JMS实现的。
(2)JMS支持两种模型
1)点对点(P2P)或队列模型
使用队列作为消息通信载体。一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息。一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。生产者不需要在接收者消费该消息期间处于运行状态,接收者也同样不需要在消息发送时处于运行状态。
2)发布者/订阅者(Publisher/Subscriber)模型
发布者/订阅者模型使用主题作为消息通信载体,0或多个订阅者可能对接收来自特定消息主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方,类似于广播模式。发布者发布一条消息,该消息通过主题传递给所有的订阅者,在该消息广播之后才订阅的用户则是收不到该条消息的。
(3)五种消息正文格式
JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JMS客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:消息头和消息主体。消息头包含消息的识别信息和路由信息。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为五种类型:
1)简单文本(TextMessage)
2)可序列化的对象(ObjectMessage)
3)属性集合(MapMessage)
4)字节流(BytesMessage)
5)原始值流(StreamMessage)
2. AMQP
(1)介绍
AMQP(Advanced Message Queuing Protocol)一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。RabbitMQ 就是基于AMQP协议实现的。
(2)工作过程
发布者(Publisher)发布消息(Message),经由交换机(Exchange)。交换机根据路由规则将收到的消息分发给与该交换机绑定的队列(Queue)。最后将消息投递给订阅了此队列的消费者,或者消费者按照需求自行获取。发布者、交换机、队列、消费者都可以有多个。