我们都知道Kafka我们平时开发中使用比较多也是比较成数的消息中间件之一。消息中间件MQ,在我们理解kafka之前,我们先来了解下MQ:
- MQ是什么.
- MQ给我们带来的好处.
- 如何设计一个简单的MQ.
一:MQ简述
MQ:简单来说就是一个生产者用于生产消息、一个消费者用于消费消息、一个消息队列用于存放消息。
其中有两个关键的信息:
1.消息:消息就是值我们可以按照自己的约定生产者封装成一个对象或者是一个json的字符串。
消费者,能按照预定比如:序列化出对象或者解析json数据,在MQ中都可以被叫做消息。
2.队列:队列其实理解为java中List,遵循FIFO的原则,它是存放消息的容器,消息从队尾入队,从队头出队,入队即发消息的过程,出队即收消息的过程。
二、MQ的通信模型
理解MQ的基本雏形以后,我们在来思考下MQ中:生产者、消息队列、消费者三者之间的通信方式。提出这个问题,我相信大家最开始能想到的通信模型:类似单播的方式:生产者生产一条消息向队列中存放一条消息。然后消费者去消费消息。也就是一条消息只能被其中一个消费者接收到,读完即被删除。也就是队列模型,三者有序的进行着、
随着业务的发展。当生产生产的一条消息。需要被多个消费者消费时,此时、显然队列模型即单播的方式是支持不了的。这时就衍生了发布订阅模式:
生产者生产一条消息:发送到队列中的一个topic(一个主题中),这个topic支持被多个消费者去订阅,当topic中存在消息后,会广播给所有订阅该主题的消费者去消费消息。
三、MQ的常用的业务场景
相信大家对MQ的使用场景都可以倒背入流了:
- 系统解耦
- 异步处理
- 流量削峰
- 延迟通知
接下来我们来分析下MQ是怎么应用到这些业务场景的。有人会问、一个中间件的产生是先有设计还会先有业务场景。可以肯定的是。肯定是先有问题产生,后面才会的逐渐完善的解决方案。肯定是先有业务场景。
那我们回过头去看下MQ的通行模型中的队列模式:
系统解耦
比如:订单系统完成了一个订单然后通知会员系统去更新会员积分。
订单系统需要调用会员系统的接口,去更新积分。
当我们有了MQ之后:订单系统完成订单后向MQ中发送一条消息、然后会员系统去消费这个消息。去更新积分,在这个过程中、订单系统和会员系统都只和消息队列即MQ有了耦合。但是订单系统和会员系统之间的耦合被解除。这就是系统解耦
异步处理
异步是说:比如一个更新订单的状态的操作,提供一个接口:这个接口中,除了要实现更新订单状态。然后还需要去更新会员积分。这是两个操作,是同步的,在一个接口中,先更新状态,在更新会员积分。当有了MQ以后,我们只需要将订单更新的消息告诉MQ。然后MQ立刻响应。做到了异步处理
流量削峰:
这个说的是,更新订单的操作的耗时需要500ms。更新会员积分的耗时需要500ms,那么有了MQ以后。更新订单还是500ms但是更新会员就能降低到10ms。大大降级了,接口的吞吐量。另外在高并发的场景下。访问接口时,可以立即发送MQ。然后立刻响应数据给到调用放,然后由MQ回调处理业务逻辑,这才是流量削峰。
四、如何设计一个MQ、以及MQ会存在哪些问题、
1、先把握这个问题的关键点
假如我们还是只考虑最基础的功能:发消息、存消息、消费消息(支持发布-订阅模式)。
那在生产环境中,这些基础功能将面临哪些挑战呢?我们能很快想到下面这些:
1、高并发场景下,如何保证收发消息的性能?
2、如何保证消息服务的高可用和高可靠?
3、如何保证服务是可以水平任意扩展的?
4、如何保证消息存储也是水平可扩展的?
5、各种元数据(比如集群中的各个节点、主题、消费关系等)如何管理,需不需要考虑数据的一致性
2、整体设计思路
我们需要的三个组件:生产者(producer)、消费者(consumer)、消息队列即MQ服务器(broker)
- producer发送消息到broker。
- broker需要对消息进行存储
- consumer消费消息
- broker得到consumer的消息确认。
- broker对消息进行备份或者删除
参考大佬的文章:
更多信息: