消息队列可以说是后端的进阶必备吧,并发增大之后,必须要去处理削峰的问题,否则应对服务很快就会瓶颈,服务崩溃,那么能够想到的直观方案就是通过消息队列去存储消息。 这样既可以保证前部的服务做到快速响应,将逻辑处理通过消息队列去解耦,一旦解耦,就可以通过增加消费者的方式来快速处理消息,加大吞吐量 又因为消息队列本身都有持久化方案,即便中间的消息出现异常,也能够做到重新消费,让服务健壮性更加的好,扩展性也更加好,比如新增加一些功能,可以通过消费旧的消息队列来快速应用。 几乎都是优点,缺点就是一致性,顺序性这些问题,根本就是并发的问题。
- 主要就是使用了 nest 的微服务来消费 kafka 的消息
- 网络上相关的内容较少,而 nest 官网的介绍也片段化,所以我完整走了一遍这个流程,并记录下来
- 使用的 docker 来部署 kafka 集群
- 没有生产环境的项目,内网做的测试。生产环境的部署,必定是不同的,感觉主要是 ip 相关,可能涉及分机器部署,随意 ip 需要暴露公网 ip,不像现在内网,大家都在一起,ip 也就不重要了。
- ssl+sasl 的版本,总也没走通,只能等后续 dockerhub 上官方更新后再看了。
- kafka 集群的扩容,尤其是生产环境,kafka 集群如何扩容?因为比如订单的消费,比如订单创建,处理,完成,具有强烈的顺序要求。看到某些方案中提到,让同一个订单的相关消息都同步到一个 partition 中,这样就可以保证消息的顺序消费。要做到这一步,需要确保每个 partition 对应一个 consumer,对于初次部署,这个方案一点问题没有,看着也很靠谱。但是我就产生了困惑,如果在生产环境做扩容,也就是说扩容 patition 同时也需要去扩容 consumer,同时还要保证服务不中断,如何做到?
- 我是使用 pm2 启动的服务,初始启动了两个服务,然后发送请求 /send,每次请求都是三万条消费数据,并发了十几万条
pm2 start dist/main.js --name=kafka-receiver -i 2
中间还进行了
pm2 scale kafka-receiver +1
扩容操作,并没有出现顺序错乱问题,因为一旦有新服务加入,所有的服务都会暂时停止,进行 rebalance,rejoin,没影响 发现用这个 nestjs 去处理的话,查看 top,cpu 占用会飙升,频繁保持 100% 占用。
感觉就这个架构,应对一般的生产环境,应该是可以的,可以快速扩容,缩容,顺序性也可以保证
-
中间其实还是去直接操作数据库了,通过 top 发现,偶尔数据库的 cpu 也会飙升到接近 100%,感觉还是风险很大的,不过最终没有异常报错 这个最简单,最直接的方案其实是可以通过的,数据库可以抗住压力的 当然上面这个方案肯定还是有问题的,毕竟等同于裸奔了,还是准备 redis 出马,抗一下压力
-
另外现在只有 12 个分区,生产环境感觉可以考虑来个五六十个分区,服务也五六十个。
-
业务逻辑的增加,毕竟现在只是最简单的逻辑处理,拿到数据直接插入,还是要考虑业务环境复杂逻辑带来的消费时间增加的问题。
-
分表的问题,表的容量还是需要控制的,方便索引的快速查找,感觉最正常的应该就是按照天来分表,将几天天的数据移出到旧表中
-
关于 pm2,看到不少评论都说 pm2 复杂度已经超多大多数项目自身,不推荐使用生产环境,但就现在使用来看,还是蛮好用的,自带的负载均衡比较方便 后续扩容可以考虑结合 nginx 的负载均衡,一起来扩容,这样可以避免将压力完全压在 pm2 这单个服务上面,