单体架构的 IM 系统设计
先直接抛出业务背景!
有一款游戏,日活跃量(DAU)在两千左右,虽然 DAU 不高,但这两千用户的忠诚度非常高,而且会持续为游戏充值;为了进一步提高用户体验,继续增强用户的忠诚度,老板想要在该款游戏中引入聊天功能,同时探索和验证游戏用户对 IM 的需求和依赖度。IM 需要在两周后上线,如果你是这个 IM 项目的架构师,带着两名经验尚欠的程序员,你如何设计并落地该 IM 系统?
业务背景并不复杂,简单总结一下:
-
用户规模小:DAU 在两千左右,同时在线人数高峰期不到200;
-
开发人员少:一名架构师加两名程序员;
-
开发时间短:一周开发加一周测试,只有两周时间。
这种情况下,研发策略通常是:怎么简单就怎么做,怎么快就怎么来!
所以对该 IM 系统采用【单体架构】的方式进行设计,见下图。
前端是运行安卓系统和 IOS 系统的移动设备,游戏 APP 内嵌 IM 的客户端,由前端同学负责开发。
后端是 Server 节点,通过多进程多机器部署的方式,避免 “单点”; 这个地方需要注意:【单体架构】并非 “单点架构” ,单体架构仍然是分布式架构的一种,通过集群的方式提供高可用和高吞吐的服务;对多个 Server 节点的访问通过 Nginx 来做反向代理;Server节点由后端同学负责开发。
存储部分包括数据库和缓存,数据库中分别创建 “消息表”、“离线消息表”、“联系人表” 和 “用户表”; 缓存用来记录用户的在线信息;数据库和缓存由 DBA 同学负责维护。
单体架构的系统,最大的优势就是在项目前期开发简单、部署简单、测试简单、运维简单,开发同学几乎可以将所有的注意力全部放在业务逻辑上,实现真正的【快速落地】。
下面分别讨论一下关键的技术选型:前端与后端的通讯协议、后端的编程语言、数据库选型。
一、通讯协议
前端与后端之间的通讯协议,有四种选择,见下表。
IM 系统通常会选择 “长连接” 类型的协议;但是 WebSocket 协议因为刚推出不久,成熟度不高;TCP 协议属于传输层协议,较为复杂,如果没有丰富的 TCP 网络编程经验的话,在研发时间非常紧张的情况下,建议不要选择 TCP。
所以,这里我们选择最简单和最容易落地的协议—Http;对于编程经验尚欠的应届生来讲,Http编程也不会有太大难度。
分析到这里,相信大家肯定有这样的疑惑:Http 是短连接的无状态协议,如何进行消息的即时通讯呢?难道是通过客户端周期性的轮询访问吗? 是的,同时在线人数只有几百的情况下,客户端周期性轮询是完全没有问题的,况且Server是多节点部署,完全可以 Cover 客户端周期轮询的压力。
二、编程语言
Server 端编程语言,也有四种选择(公司内部正在使用的技术栈),见下表。
C++、Java、PHP、Go 四门编程语言都有非常成熟的并发编程模型,这里我们选择公司和团队最熟悉的语言—Go,使用最熟悉的语言才会带来更高的编程效率和更快的问题解决速度。
三、数据库
数据库选型有三种选择,分别是关系型 SQL 数据库—MySQL、非关系型 NoSQL 数据库—MongoDB、已经新兴的NewSQL 数据库—TiDB,见下表。
在该单体架构的 IM 系统中,数据库需要提供强事务能力,来保证业务的完整逻辑;同时,数据库需要做到更低成本的运维;这里我们选择满足需求和容易运维的数据库—MySQL。
最后,总结文中关键:
1、业务背景:用户规模小、开发人员少、开发时间短;
2、研发策略:怎么简单怎么做,怎么快怎么来;
3、 IM单体架构: 前端(APP)+ Server + 数据库
单体架构最大的优势就是在项目前期开发简单、部署简单、测试简单、运维简单。
4、技术选型:
选择最简单和最容易落地的协议—Http,
选择公司和团队最熟悉的语言—Go,
选择满足需求和容易运维的数据库—MySQL。
提出一个思考问题,我们会在下篇技术短文中进行分析:
基于该IM单体架构,如何实现用户的登录和收发消息呢?Server 节点是无状态化的吗?