消息队列基础
本文参考《kafka 权威指南》、https://www.wmyskxz.com/2019/07/17/kafka-ru-men-jiu-zhe-yi-pian/ 、 https://github.com/JavaFamily、https://cloud.tencent.com/developer/article/1006035
1、 前言
消息队列也称消息中间件、消息系统。
首先,消息队列,见名,其是一种队列。那么我们数据结构中的队列是什么样的呢?
在数据结构中,队列一般是先进先出的,符合先来先服务的场景。就像你去火车站取票,甚至进站时的场景一样。
以 java 为例,你肯定熟知:
public interface Queue<E> extends Collection<E> {...}
2、 使用场景
消息队列,是一种数据管道。
当业务量很大时,微服务、分布式部署,系统间通信就成了一个难题。以往的系统间通信,使用接口调用,每增加新的业务,就必须增加接口,维护困难,等到了最后,整个系统就更加复杂难以维护。
一般而言,消息队列用于系统间通信,数据传输。**常见的场景是异步、削峰、解耦,当然也有的人拿它做缓冲、数据库、等。**嗯恩,用来聊天的就过分了啊,是qq、微信不香吗?
2.1 异步
说到异步,必须用同步做为对比,这样更加能说明问题。
接下来,我们设计一个场景:假设,你在一个网站上要注册信息,人家需要你填写你的电话,需要发送短信进行验证。一般而言,是不是需要短信发送之后,才确定你注册成功呢?如下图。
这整个过程,花费了好久。你在等待注册的同时,免不了会爆粗口啊。
那如果是下面这种情形呢,就完全不一样了:
将发送短信的请求,写入消息队列,之后就让页面直接响应给用户一个注册成功的信息。然后,系统再在其他时间(或者有其他系统帮忙消费)去消费这队列中的请求。达到一个异步处理的效果。发现没有,这样的用户体验完全不一样了呢!
2.2 削峰
这个就是一个高并发的的场景了。见过双11的秒杀活动吗?在短时间内,访问量剧增的场景。
这里有一段数据库和程序员之间的对话(玩笑而已,不必深究):
程序员:哇,公司的人又多了好多啊,今年虽然是寒冬,但是还招了不少新鲜血液。
数据库:恩。确实,可是我有点担心…
程序员:担心?什么啊?
数据库:大家上班、下班打卡啊,平时的话还好,要是上班高峰期就坏了。我可以支撑每秒2000次访问,可是如果超过这个数量,那我可能要“受伤”,就不能继续为广大、帅气、美丽的朋友们提供服务了啊!
程序员:你是说,在1秒内,如果有3000、5000次,甚至更多的操作直接找你服务,你会宕机?
数据库老脸一红,不好意思的点了下头。
程序员:没关系,我呀,加个缓冲,过滤掉一部分的操作。让2000以下的操作去你那吧。其他过滤掉的操作,就先放在队列中,你呢,每次会给你一部分去操作啦。
数据库:恩,真好。
接下来,我们看这个缓冲队列是怎么加的?
2.3 解耦
这个思想其是挺容易理解的。举个例子:
系统 A 依赖着系统 B 和 C。A 中需要调用 B 和 C 中的接口,因此 A 中提供了该业务对应的接口。那当我们增加 A 所依赖的系统的个数时,需要改动的地方会很多,系统间的耦合度也会增加,不易维护。
这种情形,可以使用消息队列来解决。
这样一来,无论增加多少个系统,A 系统只需要将消息发送到消息队列,由其他系统拉取消息进行消费即可。系统的耦合性也体现在系统的减少上,假如现在要撤了系统 B ,那对于整个系统而言,只是少了消费的系统而已,无伤大雅。
2.4 日志处理
将大量日志存储到消息队列中(一般使用分布式消息队列 kafka),解决大量日志传输的问题。
2.5 聊天
真的,有人会用消息队列弄个聊天室的。
3、常见的消息队列
ActiveMQ、RabbitMQ、RocketMQ、Kafka等。