MQ消息队列学习
1.概念:(message queue)
一种跨进程的通信机制,用于在上下游之间传递消息。消息发送上游只需要依赖MQ,逻辑上和物理上都不用依赖其他服务
详解参考:https://blog.csdn.net/wqc19920906/article/details/82193316 ;https://blog.csdn.net/u010255818/article/details/77855873
2.使用场景:
- 应用解耦:比如:某系统发生故障时,将要处理的数据暂存到消息队列中,等系统恢复时,继续处理相关信息,用户不会感受到系统的故障。
- 流量消峰:比如一秒钟订单系统的处理上限是一万个订单,如果两万个订单,超出上限时,可以将这一秒中的订单分批处理,有的可能会十几秒、有的可能一秒就可以得到订单成功的结果。
- 消息分发:多个服务对同一个数据感兴趣,只需要监听同一类消息就可以。比如A、B、C。B和C对A数据都感兴趣,那么A就可以作为基础服务,只管发送消息,其他负责监听就行
- 异步消息:比如A服务调用B服务时,B需花费一定的时间去执行,有两种方式去告知A执行完毕。A过一会去调用B的查询接口,或者B调用A的callback接口。 !!!But 通过使用mq,只需要监听B服务是否完成,如果完成会发送一条消息给mq,mq会将该消息发送给A。从而A得知B已完成
注意:MQ只用来传递上游任务执行完成的消息,并不用于传递真正的输入输出数据。 - 1)数据驱动的任务依赖; 2)上游不关心多下游执行结果; 3)异步返回执行时间长时,可以使用mq。但是调用和被调用是无法被取代的,上游需要收到执行的结果时,不能用mq。(用户登录时,密码服务的结果会直接影响登录,所以不能用mq)
参考:https://www.jianshu.com/p/9a0e9ffa17dd
mq使用场景及分析: https://blog.csdn.net/u010255818/article/details/77855873
3.不足:
系统更复杂,多了一个MQ组件;消息传递路径更长,延时会增加;消息不丢不重难以同时保证;上游无法知道下游的执行结果
4.消息队列mq的原理:
JMS(Java消息服务) 是一个 Java 平台中关于面向消息中间件(MOM)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
有两种消息模式,点对点和发布者订阅者 https://zhuanlan.zhihu.com/p/99791229 ;https://blog.csdn.net/hudfang/article/details/80583598
- 点对点模式:P2P(point to point)
producter生产者 ——->[Queue]——-> consumer消费者
! 生产者发送一条消息到queue,只有一个消费者能收到。Queue支持存在多个消费者 ! (即一旦被消费,消息就不再在消息队列中)
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。
queue 实现了负载均衡,一个消息只能被一个消费者消费。当没有消费者的时候,会一直保存到有下一个可用的消费者,多个消费者之间实现了负载均衡。多个消费者对于队列内的消息是竞争消费关系
接收者在成功接收消息之后需向队列应答成功,如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。 发布者/订阅者模式:
publisher发布者 ——->[topic]——-> subscriber订阅者
!发布者发送到topic的消息,只会被订阅了topic(订阅主题,唯一)的订阅者消费!
为了消费消息,订阅者必须保持运行的状态!
topic:一个订阅主题是由至少一个队列(Queue)组成。
除非订阅者创建了持久的订阅,在订阅者未连接时发布的消息将在订阅者重新连接时重新发布,每个消费者都能收到全量的消息。即消息重发
如果希望不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型
参考:
https://www.cnblogs.com/aspirant/p/8778891.html
https://blog.csdn.net/h2604396739/article/details/81136527
https://www.jianshu.com/p/689ce4205021
5.MQ实现流程:
MQ-client-sender——>MQ-server——->MQ-client-receiver
1.MQ-client 接收方 将消息发送给MQ-server(此时业务方调用的是API:SendMsg);
2.MQ-server将消息落地,即保存到数据库或硬盘,落地后即为发送成功;
3.发送成功后,MQ-server将应答发送给MQ-client(此时回调业务方是API:SendCallback)
4.MQ-server将消息发送给MQ-client 消费方(此时回调业务方是API:RecvCallback);
5.消费成功后,MQ-client回复应答给MQ-server(此时业务方主动调用API:SendAck);
6.MQ-server收到ack,将之前已经落地的消息删除,即删掉数据,完成消息的可靠投递
重传:1、4步重新发起,针对每一条消息,mq内部生成唯一id,可以保证去重
第四步,消费方通过生成消息数据唯一标识,同一个标识只能消费一次,来实现去重
还没有评论,来说两句吧...