消息队列与Kafka

关于消息队列

消息队列(如下简称MQ)是一种跨进程的通讯机制,用于上下游传递消息。前端

什么时候使用

  1. 异步处理:主要的使用场景就是将比较耗时并且不须要即时(同步)返回结果的操做做为消息放入消息队列,有利于下降请求响应时间。例如:高并发状况下用户注册时,因为邮件接口承受不住,可能会出现用户记录已经添加到数据库记录中可是系统却卡在发送注册邮件中,致使请求响应的时间大幅增长,甚至出现超时,面对这种状况通常也是将这些操做放入消息队列(生产者消费者模型),消息队列慢慢的进行处理,同时能够很快的完成注册请求,不会影响用户使用其余功能。因此在软件的正常功能开发中,并不须要去刻意的寻找消息队列的使用场景,而是当出现性能瓶颈时,去查看业务逻辑是否存在能够异步处理的耗时操做,若是存在的话即可以引入消息队列来解决。不然盲目地使用消息队列可能会增长维护和开发的成本却没法获得可观的性能提高,那就得不偿失了。
  2. 解耦:因为使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不须要彼此联系,也不须要受对方的影响,即解耦和。多个应用之间的耦合,因为消息是平台无关和语言无关的,并且语义上也再也不是函数调用,所以更适合做为多个应用之间的松耦合的接口。基于消息队列的耦合,不须要发送方和接收方同时在线。同时可用于分布式系统,各个不一样的进程(同一台机器或者不一样机器)经过消息队列进行通讯。
  3. 削峰:好比订单处理,就能够由前端应用将订单信息放到队列,后端应用从队列里依次得到消息处理,高峰时的大量订单能够积压在队列里慢慢处理掉。因为同步一般意味着阻塞,而大量线程的阻塞会下降计算机的性能。好比你的服务器一秒能处理100个订单,但秒杀活动1秒进来1000个订单,持续10秒,在后端能力没法增长的状况下,你能够用消息队列将总共10000个请求压在队列里,后台consumer按原有能力处理,100秒后处理完全部请求(而不是直接宕机丢失订单数据)。

典型场景

1.数据驱动的任务依赖数据库

如:定时任务tast1, task2, task3之间存在任务依赖关系,必须task1先执行,再task2执行,载task3执行后端

此时,MQ用来传递上游任务执行完成的消息。服务器

2.上游不关心执行结果微信

  • 上游执行时间短
  • 上下游逻辑+物理解耦,除了与MQ有物理链接,模块之间都不相互依赖
  • 新增一个下游消息关注方,上游不须要修改任何代码

3.上游关注执行结果,但执行时间很长架构

跨公网调用微信支付接口,使用回调网关+MQ来解耦。并发

不适合的场景

调用与被调用的关系,是没法被MQ取代的。运维

用户登陆场景,登陆页面调用passport服务,passport服务的执行结果直接影响登陆结果,此处的“登陆页面”与“passport服务”就必须使用调用关系,而不能使用MQ通讯。异步

不管如何,记住这个结论:调用方实时依赖执行结果的业务场景,请使用调用,而不是MQ。分布式

使用MQ可能存在的问题:

RPC与MQ的区别

远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合

Kafka

吞吐量极高的分布式消息系统,总体设计是典型的发布与订阅系统。下图1为Kafka架构图:

                                图-1 Kafka架构图

主要术语

消息生产者:即Producer,消息源头,负责发送消息并发送到Kafka服务器上。

消息消费者:即Consumer,消息的使用方,负责消费Kafka服务器上的消息。

主题:Topic,用户配置并定义在Kafka服务端,用于创建生产者和消费者之间的订阅关系:生产者发送消息到指定topic下,消费者从这个topic下订阅消息。

参考连接

芋道源码-【消息队列 MQ 专栏】消息队列之Kafka

高效开发运维-漫谈消息队列:以Kafka和RocketMQ为例

芋道源码-为何须要消息队列?使用消息队列有什么好处?(主流消息队列对比)

InfoQ-Kafka系列

orchome-Kafka中文教程

芋道源码-分布式消息队列RocketMQ源码分析—Message顺序发送与消费(顺序消费问题,RocketMQ支持可是通常场景不推荐使用,Kafka只能保证每一个partition内的消息顺序传输)