消息队列(一)消息队列的工作流程
什么是消息队列
首先,代入一个场景,我现在做一个多系统的集成,分别有系统A、B、C、D四个系统,A系统因为使用产生了业务数据,B、C、D需要使用这些数据做相关的业务处理和运算,最基本的做法就是通过接口通信,即A根据数据的变化情况通过调用B、C、D的接口,向它们推送产生的数据。
但是此种解决方案的问题也比较明显,首先就是系统间的耦合加重,扩展性较差,A 系统产生一条比较关键的数据,另外的系统都需要 A 系统将这个数据发送过来,就需要A进行定向的开发接口,对于系统间也需要考虑容错(发送失败?重发机制等等);如果此时新增了E系统需要数据,或者D系统不需要了,A系统就需要进行开发绑定;
在这种情况下,如果在A和BCD之间有一个第三方,A负责将数据交给第三方,而BCD甚至后面新增的E,都可以按需去第三方去取或者不去取,消除了A和其他系统的耦合,此外也减少了A的程序变更成本。这个第三方就是消息队列(MQ)。
消息队列的优缺点
优点
消息队列的优势主要有三点:就是解耦、异步、削峰。
解耦已经在上文中体现了,通过第三方的MQ组件,能够降低集成系统间的耦合,减少不必要的定向API代码,使其扩展性得到保证。
关于异步主要体现在当一组数据变化,需要多处写入时,耗时则是时间的顺序加和,体验较差,而引入消息队列,则可以在一处完成后即刻响应。
消息队列的另一个优势就是缓冲,在系统使用的高峰期,每秒并发请求数量是非常巨大的,此时数据层的并发能力受限于数据库,未必能够满足这种级别的并发,而数据又不能暂停等待数据库写入,此时,消息队列就可以居中起到缓冲消峰的作用。
请求或数据先进入到队列中暂存,由数据库逐步写入,而不影响正常的使用。
缺点
和系统设计中引入其他组件一样,引入新组件后,系统的复杂度就会变高,系统的设计和开发成本也会隐式增长;主要体现在,引入消息队列后, 需要新增策略保证消费机制的完整(防重复、数据一致性、消息顺序性等) 。
另一个缺点就是系统的可用性受限,引入消息队列后,消息队列组件本身的稳定性也会传递到当前的系统中(例如:消息队列崩溃,系统的部分功能也将瘫痪)。
而使用消息队列的技术要点就是尽量取规避和解决引入消息队列所带来的负面影响。
常用消息队列组件的比对
单机吞吐量 | topic 数量对吞吐量的影响 | 时效性 | 可用性 | 消息可靠性 | 功能支持 | |
---|---|---|---|---|---|---|
ActiveMQ | 万级,比 RocketMQ、Kafka 低一个数量级 | topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降 | ms 级 | 高,基于主从架构实现高可用 | 有较低的概率丢失数据 | MQ 领域的功能极其完备 |
RabbitMQ | 同 ActiveMQ | 在同等机器下,topic 数量增加时,吞吐量会受到影响,但具体影响程度需要根据实际情况确定(注:原始信息中关于此点描述为 Kafka 的情况,这里进行了调整) | 微秒级,这是 RabbitMQ 的一大特点,延迟最低 | 同 ActiveMQ | 基本不丢 | 基于 Erlang 开发,并发能力很强,性能极好,延时很低 |
RocketMQ | 10 万级,支撑高吞吐 | 这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic,topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降 | ms 级 | 非常高,分布式架构 | 经过参数优化配置,可以做到 0 丢失 | MQ 功能较为完善,还是分布式的,扩展性好 |
Kafka | 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景 | 在同等机器下,topic 数量过多时,吞吐量会大幅度下降,如果要支撑大规模的 topic,需要增加更多的机器资源 | 延迟在 ms 级以内 | 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 | 同 RocketMQ | 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用 |