Java中间件学习之RabbitMQ

什么是MQ

 

 消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦

MQ是消息通信的模型,并不是具体实现。现在实现MQ的有两种主流方式:AMQPJMS

AMQP:

AMQP是一个提供统一消息服务的应用层标准协议,是应用层协议的一个开放标准,为面向消息的中间件设计。它是一个二进制级别的协议,直接定义网络交换的数据格式,而不从API层进行限定。AMQP支持跨语言、跨平台,任何遵守此数据格式的工具都能与其他兼容工具进行互操作。

JMS:

JMS是Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间或分布式系统中发送消息,进行异步通信。它定义了统一的接口来对消息操作进行统一,但限定了必须使用Java语言。

两者间的区别和联系:

  1. JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
  2. JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
  3. JMS规定了两种消息模型;而AMQP的消息模型更加丰富

补充:

  • ActiveMQ:基于JMS
  • RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
  • RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
  • Kafka:分布式消息系统,高吞吐量

MQ的好处

  • 流量消锋
  • 应用解耦
  • 异步处理

MQ的对比和选择

 

RabbitMQ的组成部分

  • 生产者Producer产生数据发送消息的程序是生产者。
  • 交换机Exchange交换机是 RabbitMQ 非常重要的一个部件,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息,是将这些消息推送到特定队列还是推送到多个队列,亦或者是把消息丢弃,这个得有交换机类型决定。
  • 队列Queue队列是 RabbitMQ 内部使用的一种数据结构,尽管消息流经 RabbitMQ 和应用程序,但它们只能存储在队列中。队列仅受主机的内存和磁盘限制的约束,本质上是一个大的消息缓冲区。许多生产者可以将消息发送到一个队列,许多消费者可以尝试从一个队列接收数据。这就是我们使用队列的方式。
  • 消费者Consumer消费与接收具有相似的含义。消费者大多时候是一个等待接收消息的程序。请注意生产者,消费者和消息中间件很多时候并不在同一机器上。同一个应用程序既可以是生产者又是可以是消费者。

 MQ的工作模式

  • Hello Wold 简单模式:简单的“生产者-消息队列-消费者”的工作模式。
  • Work queues工作 队列模式:一个消息队列对应多个消费者,由多个消费者竞争消费信息。
  • Publish/Subscribe发布订阅模式:引入交换机Exchange,类型为Fanout,特点是将消息分发到绑定的多个消息队列中。
  • Routing 路由模式:这种模式下的交换机类型为Direct,特点是可以根据指定的Routing Key去匹配BindingKey相同的消息队列。
  • Topics 主题模式:这种工作模式的交换机类型为Topic,特点是RoutingKey和BindingKey中引入通配符,然后两者通过模糊匹配相关联。
  • Publisher Confirms 发布确认模式(RPC):这种工作模式实际应用不广泛暂不学习。

补充:生产者(Producter)和交换机(Exchange)之间通过RoutingKey相关联,交换机(Exchange)和消息队列(Queue)之间通过BindingKey来绑定。

RabbitMQ如何避免消息丢失

生产者:在生产者端开启comfirm 确认模式,生产消息发到RabbitMQ后,会给你回传一个ack消息,告诉你说这个消息成功写入了。

消息队列:消息队列设置为持久化队列,将内存数据持久化到磁盘中。

消费者:消费者把自动ACK关闭,设置为手动ACK,等消息被消费以后再返回ACK信息。

RabbitMQ如何保证顺序性消费

方案一:拆分多个Queue,每个Queue对应一个Consumer。(性能慢,需要增加Consumer的数量,风险小一点)

方案二:Producter和Consumer根据实际业务制定好规则,然后Consumer增加本地缓存或者队列,将消息按规则拍好顺序后消费,如果觉得效率慢可以引入多线程去处理。(不需要增加Consumer,性能快,如果用多线程风险会高一些)

RabbitMQ如何幂等性消费信息(不重复消费信息)

每条消息绑定一个不重复的Id作为标识,消费方在消费的时候通过Id去判断是否已经被消费。例如消费方可以把信息先存到数据库中,把Id作为主键,如果主键冲突说明此条消息已被消费过,然后再根据实际业务场景选择由插入数据改为更新,或者直接舍弃掉。

posted @ 2023-03-09 10:37  请别耽误我写BUG  阅读(90)  评论(0编辑  收藏  举报