千呼万唤始出来,这篇教程拖了一个星期。最近准备暑期实习实在没时间,因为没经验,我都不知道三月份暑期实习招聘就开始了 ?,留给我的时间有点短,正好今天复习 Kafka,所以抽点时间来写篇教程。
其他的常见技术栈就不说了,MyBatis、Redis 等,本文只讲 Spring Boot 和 Kafka,当然,Kafka 是重中之重,Spring Boot 就简单分析一下优点就完事儿。
为什么选择 Spring Boot?
1)从字面理解,Boot 是引导的意思,Spring Boot 可以帮助我们迅速的搭建 Spring 框架;
2)“约定大于配置”,一般来说,我们使用 Spring Boot 的时候只需要很少的配置,大部分情况下直接使用默认的配置即可;
3)Spring Boot 内嵌了 Web 容器,降低了对环境的要求,使得我们可以执行运行项目主程序的 main 函数;
4)最重要的,对于开发者来说,那当然是 Spring Boot 不需要编写大量的 XML 配置;
5)..........
为什么选择 Kafka?
为什么使用消息队列
先来说一下为什么要使用消息队列,六个字总结:解耦、异步、消峰。
1)「解耦」
传统模式下系统间的耦合性太强。怎么说呢,举个例子:系统 A 通过接口调用发送数据到 B、C、D 三个系统,如果将来 E 系统接入或者 B 系统不需要接入了,那么系统 A 还需要修改代码,非常麻烦。
如果系统 A 产生了一条比较关键的数据,那么它就要时时刻刻考虑 B、C、D、E 四个系统如果挂了该咋办?这条数据它们是否都收到了?显然,系统 A 跟其它系统严重耦合。
而如果我们将数据(消息)写入消息队列,需要消息的系统直接自己从消息队列中消费。这样下来,系统 A 就不需要去考虑要给谁发送数据,不需要去维护这个代码,也不需要考虑其他系统是否调用成功、失败超时等情况,反正我只负责生产,别的我不管。
2)「异步」
先来看传统同步的情况,举个例子:系统 A 接收一个用户请求,需要进行写库操作,还需要同样的在 B、C、D 三个系统中进行写库操作。如果 A 自己本地写库只要 1ms,而 B、C、D 三个系统写库分别要 100ms、200ms、300ms。最终请求总延时是 1 100 200 300 = 601ms,用户体验大打折扣。
如果使用消息队列,那么系统 A 就只需要发送 3 条消息到消息队列中就行了,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 1 5 = 6ms,对于用户而言,体验好感度直接拉满。
3)「消峰」
如果没有使用缓存或者消息队列,那么系统就是直接基于数据库 MySQL 的,如果有那么一个高峰期,产生了大量的请求涌入 MySQL,毫无疑问,系统将会直接崩溃。
那如果我们使用消息队列,假设 MySQL 每秒钟最多处理 1k 条数据,而高峰期瞬间涌入了 5k 条数据,不过,这 5k 条数据涌入了消息队列。这样,我们的系统就可以从消息队列中根据数据库的能力慢慢的来拉取请求,不要超过自己每秒能处理的最大请求数量就行。
也就是说消息队列每秒钟 5k 个请求进来,1k 个请求出去,假设高峰期 1 个小时,那么这段时间就可能有几十万甚至几百万的请求积压在消息队列中。不过这个短暂的高峰期积压是完全可以的,因为高峰期过了之后,每秒钟就没有那么多的请求进入消息队列了,但是数据库依然会按照每秒 1k 个请求的速度处理。所以只要高峰期一过,系统就会快速的将积压的消息给处理掉。
为什么选择 Kafka
再来看看在 Echo 这个项目中,哪些地方使用了消息队列也就是 Kafka:
- 评论、点赞、关注事件触发通知
- 发帖事件触发 Elasticsearch 服务器中相应的数据更新
- 删帖事件触发 Elasticsearch 服务器中相应的数据更新
实际上在早期的时候 Kafka 并不是一个合格的消息队列,不过现在已经足够优秀。不说我们这个用户量比较小的论坛,从大体量的论坛项目来考虑,我觉得 Kafka 比较适合的原因有如下:
1)Kafka 天生支持分布式,Broker、Producer 和 Consumer 都原生自动支持分布式;
2)Kafka 拥有多分区(Partition)和多副本(Replica)机制,能提供比较好的并发能力(负载均衡)以及较高的可用性和可靠性,理论上支持消息无限堆积;
3)而且,在一众消息队列里,Kafka 的性能是比较高的。点赞、关注、私信等操作都会触发通知,在流量巨大的社交论坛网站中,这个系统通知的需求是非常庞大的,为保证系统的高性能,使用消息队列 Kafka 是个明智的选择。