Linux编程:--消息队列(MessageQueue)相关概念和原理

 

一、消息队列概述

消息队列(MessageQueue,简称为MQ)
其本质是就是个队列,FIFO先进先出,只不过是队列中储放的主要内容是message,因而叫消息队列
主要用于:不同的服务server、进程process、线程thread相互间通信
二、选用消息队列的场景
①异步处理
②流量控制
③服务解耦
④发布订阅
⑤高并发缓冲

①异步处理
选用场景有短信提醒、终端状态推送、App推送、用户注册等
以秒杀系统为例:
如果不选用消息队列(同步处理):假如选用同步处理,那 当客户成功消费之后,会先写进订单(例如在淘宝中生成一条订单信息),随后再通过短信提醒客户下单成功,最后再在系统中统计这条订单信息
假如选用消息队列(异步处理):当客户成功消费之后,将信息写进消息队列,随后选用1种发布订阅模型,消息队列属于发布者,“订单、短信、统计”三者属于订阅者,这样,“订单、短信、统计”三者可以同时从消息队列中获取信息,就是1种异步处理的操作了.

Linux编程:--消息队列(MessageQueue)相关概念和原理

优点: 更快速返回结果
减少等待,实现并发处理,提升系统总体性能

 

②流量控制(削峰)

使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的目的
例如下图所示,在秒杀场景下:当多个用户通过APP抢购物品,那么就会同时向消息队列中写入数据,当消息队列中数据存满时,那么数据就不能再写入了,此时服务器就会给客户端APP回送一条类似于“淘宝双11时显示的系统繁忙,请稍后再试”的信息,从而达到流量控制


扩容的概念:通过上面我们知道,当消息队列写满之后,说明你的后端服务处理达到了极限,此时可以通过增加后端服务器的数量等来进行扩容,从而可以接收更多的服务器请求。如下图所示:


③服务解耦

使用消息队列实现系统的解耦
传统的发布订阅模式中:A系统负责数据分发,D系统、B系统、D系统分别来接收数据,因为不同系统的类型不同,因此A系统需要分别针对不同的系统调用其相关接口来对其进行服务。当有新系统加入时(例如下图的E系统),那么A系统就要修改源代码,来新增对E系统的接口实现服务。这样看来系统的耦合度太高


当使用消息队列的发布订阅模式之后:A系统直接将内容写入MQ中,然后其他系统也直接从MQ中读取数据,因为MQ的接口是统一的,因此大家使用一套就可以了。这样就使得系统的耦合性降低

 

④发布订阅
比如游戏里面跨服: 广播今天整体还剩多少把屠龙刀可以暴
广播用户暴的屠龙刀的消息

 

⑤高并发缓冲
日志服务(kafka在日志服务用的比较多)、监控上报


三、消息队列的相关概念和原理


Broker

Broker的概念来自与Apache ActiveMQ,通俗的讲就是MQ的服务器

 

消息的生产者、消费者

消息生产者(Producer):发送消息到消息队列
消息消费者(Consumer):从消息队列接收消息

 


点对点消息队列模型

消息生产者向一个特定的队列发送消息,消息消费者从该队列中接收消息
消息的生产者和消费者可以不同时处于运行状态。 每一个成功处理的消息都由消息消费者签收确认 (Acknowledge)

 


发布订阅消息模型-Topic

发布订阅消息模型中,支持向一个特定的主题Topic发布消息,0个或多个订阅者接收来自这个消息主题的消息
在这种模型下,发布者和订阅者彼此不知道对方。实际操作过程中,发布订阅消息模型中,支持向一个特定的主题Topic发布消 息,0个或多个订阅者接收来自这个消息主题的消息


RabbitMQ是点对点的消息队列模型,但是可以通过路由进行配置实现发布订阅。如下图所示:

 


消息的顺序性保证

基于Queue消息模型,利用FIFO先进先出的特性,可以保证消息的顺序性

 

消息的ACK确认机制

即消息的Ackownledge确认机制, 为了保证消息不丢失,消息队列提供了消息Acknowledge机制,即ACK机制:

当Consumer确认消息已经被消费处理,发送一个ACK给消息队列,此时消息队列便可以删除这个消息了
如果Consumer宕机/关闭,没有发送ACK,消息队列将认为这个消息没有被处理,会将这个消息重新发送给其他的Consumer重新消费处理

类似于TCP的ACK机制

 

消息的持久化

消息的持久化,对于一些关键的核心业务来说是非常重要的,启用消息持久化后, 消息队列宕机重启后,消息可以从持久化存储恢复,消息不丢失,可以继续消费处理
ZeroMQ不支持持久化,其他消息队列支持

 

消息的同步和异步收发

同步:消息的收发支持同步收发的方式
同时还有另一种同步方式:同步收发场景下,消息生产者和消费者双向应答模式,例如: 张三写封信送到邮局中转站,然后李四从中转站获得信,然后在写一份回执信,放到中转站,然后张三去取,当然张三写信的时候就得写明回信地址消息的接收如果以同步的方式(Pull)进行接收,如果队列中为空,此时接收将处于同步阻塞状态,会一直等待,直到消息的到达
异步:消息的收发同样支持异步方式:
异步发送消息,不需要等待消息队列的接收确认
异步接收消息,以Push的方式触发消息消费者接收消息

 

消息的事务支持

消息的收发处理支持事务
例如:在任务中心场景中,一次处理可能涉及多个消息的接收、处理,这处于同一个事务范围内,如果一个消息处理失败,事务回滚,消息重新回到队列中


 

Linux编程:--消息队列(MessageQueue)相关概念和原理

上一篇:.net core api 防止相同参数频繁请求


下一篇:快递单号识别API 快递鸟接口