消息队列

时间:2024-11-12 04:19:39编辑:阿星

消息队列概念

消息本质上是一种数据结构(当然,对象也可以看做是一种特殊的消息),它包含消费者与服务双方都能识别的数据,这些数据需要在不同的进程(机器)之间进行传递,并可能会被多个完全不同的客户端消费 队列(Queue) ,是先进先出(FIFO, First-In-First-Out)的线性表,通俗的讲队列就是一群人或者事物按照排好的顺序等待接受服务或者处理 本地队列按照功能可划分为初始化队列,传输队列,目标队列和死信队列。初始化队列用作消息触发功能。传输队列只是暂存待传的消息,条件许可的情况下,通过管道将消息传送到其他的队列管理器。目标队列是消息的目的地,可以长期存放消息。如果消息不能送达目标队列,也不能再路由出去,则被自动放入死信队列保存。 只是一个队列定义,用来指定远端队列管理器的队列。使用了远程队列,程序就不需要知道目标队列的位置。 模型队列定义了一套本地队列的属性结合,一旦打开模型队列,队列管理器会按照这些属性动态地创建出一个本地队列。 MQ全称(Message Queue)又名 消息队列 ,是一种 异步通讯 的 中间件 。可以将它理解成邮局,发送者将消息传递到邮局,然后由邮局帮我们发送给具体的消息接收者(消费者),具体发送过程与时间我们无需关心,它也不会干扰我进行其它事情。 它被广泛的应用与跨平台、跨系统的分布式系统之间,为它们提供高效可靠的异步传输机制 JMS(JAVA Message Service,java消息服务)是java的消息服务 JMS是一套 API,是j2EE标准的一部分。 JMS是由Sun公司早期提出的消息标准,旨在为java应用提供统一的消息操作,包括create、send、receive等 JMS是Java Enterprise Edition的一部分。从使用角度看,JMS和JDBC担任差不多的角色,用户都是根据相应的接口可以和实现了JMS的服务进行通信,进行相关的操作 结构图 说明 使用 队列(Queue) 作为消息通信载体;满足 生产者与消费者模式 ,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送100条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。) 结构图 说明 发布订阅模型(Pub/Sub) 使用 主题(Topic) 作为消息通信载体,类似于 广播模式 ;发布者发布一条消息,该消息通过主题传递给所有的订阅者, 在一条消息广播之后才订阅的用户则是收不到该条消息的 。 AMQP(advanced message queuing protocol) 是一个提供统一消息服务的应用层标准协议,基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,可以跨语法开发 AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议),兼容JMS

常用的消息队列

一、redis消息队列和kafka消息队列的比较

  1、Redis作为消息队列

  Redis的pub-sub模式非常像西式快餐一样,快产快消,全都是因为Redis是使用内存来做存取,所有你生产的消息立马会被消费者一次性全部处理掉,并且没有留下任何痕迹, 同时因为内存总是宝贵的,所以内存上会有限制,当生产者以及消费者上来的时候也会对redis的效率,还有Redis在处理发布和消费big size(10K+的文件)的数据的时候会表现出无法忍受的缓慢




如果有以下场景可以考虑使用Redis作为消息队列:




a、如果你的需求是快产快消的即时消费场景,并且生产的消息立即被消费者消费掉

  b、如果速度是你十分看重的,比如慢了一秒好几千万这种

  c、如果允许出现消息丢失的场景

  d、如果你不需要系统保存你发送过的消息,做到来无影去无踪

  e、需要处理的数据量并不是那么巨大




2、KafKa作为消息队列

  KafKa的设计精妙,支持分布式,高可用的部署,并且对一个大的队列采用分成多个Partition(分区),来提高消息入队的吞吐量,分而治之的思想. 并且消费的时候支持group的概念,能够支持多个客户端消费同个队列,并且一个group中可以增加consumer的数量来扩展消费的处理量.




KafKa不熟生产者数量的影响,因为吞吐量足够支撑,即使在廉价的单机服务器上也可以有10万每秒的消息传输量,并且消费者是想什么时候消费都可以,消息它就在那里,十分灵活,不用担心来无影去无踪的恐慌.能把消息持久化,并以一定的策略(例如一定时间内删除,或者到达多大容量的时候清空)




当有一下场景的时候你可以考虑使用KafKa作为消息队列:

  a、如果你想要稳定的消息队列

  b、如果你想要你发送过的消息可以保留一定的时间,并不是无迹可寻的时候

  c、如果你无法忍受数据的丢失

  d、如果速度不需要那么的快

  e、如果需要处理数据量巨大的时候


Node下RabbitMQ的使用

github Message acknowledgment 消息回执 在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除;如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。 Message durability 消息持久化 将队列中的消息进行本地持久化存储,避免因为意外原因导致丢失的大部分消息,通过设置 durable: true Prefetch count 消息处理树 通过设置每一个消费者处理消息的数量,如果没有完成确认,就不再派发消息给消费者 exchange 交换器 生产者并不直接将消息发送到对应队列中,而是先发送到exchange 交换器中,交换器再通过一定的规则分发给一个或多个队列。交换器有四种类型: routing key 路由key(生产者定义) 生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联合使用才能最终生效。 在Exchange Type与binding key固定的情况下(在正常使用时一般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。 RabbitMQ为routing key设定的长度限制为255 bytes。 routing key 作用于发送的消息上 Binding Bindg将exchange和Queue联系起来 Bing作用于消息队列Queue上 Exchange Types 交换器的类型 RPC 远程过程调用 消息队列本身并不具备回调的功能,即发出一个消息后,生产者并不知道消费者返回的消息(能够知道是否消费,通过 ch.ack(msg) ),通过RPC能够返回消费者的消息。其原理在于新建一个replyQueue,消费者在之前订阅该队列 思考:在HTTP1.1的情况下,server 接收到前端响应提交消息,与接收到replyQueue的消息是两个独立的事件,没办法在前者的响应中加上后者返回的信息。因此只能通过ws协议实现推送。 P.S 参考资料 RabbitMQ基础概念详细介绍

上一篇:选择恐惧症

下一篇:没有了