IM后端系统设计总结(1)
文章目录
定义IM
为用户提供即时消息服务,这里面有三个关键词:用户,消息,服务;下面根据三个关键词来展开总结,先从消息开始。
消息
消息分类
对消息分类,很简单但是重要,方便后面业务的拆分。
- 注册
- 登录
- 用户信息
- 聊天消息
- 群组
- 好友
- 文件
- 版本
- 内部服务器之间消息
- 客户端诊断
- 其他业务消息
信息语义描述
在互联网和移动互联网时代常见有以下几种方式:
- XML
- 文本
- MQTT
- 自定义二进制(这里一般默认为google protobuf)
这四种类型比较如下表所示:
比较项 | XML | 文本 | MQTT | 自定义二进制 |
---|---|---|---|---|
可读性 | 好 | 好 | 差 | 差 |
通用性 | 标准协议,易通用 | 支持通用http协议,也可自定义 | 通用标准协议 | 私有协议,无法通用 |
扩展性 | 易扩展,支持第三方 | 易扩展 | 可扩展 | 仅协议可扩展,不支持第三方 |
流量消耗 | 极大 | 大 | 小 | 小 |
处理效率 | 低 | 一般 | 高 | 高 |
网络适应性 | 差 | 一般 | 较好 | 较好 |
业内应用 | 新浪微博/GTalk | MSN | facebook messenger | QQ/weixin |
再补充说一点,采用二进制协议,在网络带宽及消息存储方面可以节约成本,特别用户量达到千万级以上
参考业内应用和移动互联网需求,二进制协议应该是不二选择。这里强烈推荐google protobuf,理由如下:
- 亲爹是google
- 支持多种编程语言(C++, JAVA, PYTHON, GO,PHP,C#),支持多种平台
- 自定义且灵活
- 支持数据压缩
- 完整的技术生态,以及多年的应用实践
消息可扩展性
自定义二进制消息(google protobuf)可扩展性方面的一些经验:
- 采用T(ype)L(ength)V(alue)
- 数据结构中的成员不要使用变长数据类型,例如long,在32位系统中占4Bytes,在64位系统占用8Bytes
- 不删除消息体的数据成员
- 消息类型递增,不删除消息类型,即使不再使用也保留
- 消息头带上版本号,客户端无需要关心版本变化,由服务器完成不同版本的兼容适配处理
- 消息头与消息体的设计统一管理,不允许任何人私自修改
- 除非确定,protobuf消息字段尽量使用optional,由代码逻辑确定是否需要相应字段
- 考虑业务需求与变化,为未来留有应对变化的空间,同时保证消息的简洁
消息存储
- 初期简单点,采用mysql,同时利用mysql主备部署解决单点故障问题,分布式存储后面再说了,针对大量的消息存储后面考虑
- 对用户之间的聊天消息分表
- 对群信息等利用redis缓存
- 对于热点数据可以直接加载到内存
消息转发
- 消息从用户到用户(单播)
- 消息从用户到服务器 (单播)
- 消息从用户到群组 (组播)
- 消息从服务器到用户(单播)
- 消息从服务器到群组(组播)
消息传输
相对于PC互联网情况下,移动互联网情况下,丢包概率高,传输延迟大,问题自然就比较多,这方面优化请参考手机QQ的移动网络实践之路
消息安全
- 防修改 消息检查或校验
- 防窃听 消息加密
- 防泄漏 系统防入侵,系统加固
- 防丢失 消息请求与回应机制,消息重传与幂等性
- 防损坏 多副本,分布式存储
- 防伪装 身份验证,签名
消息描述
消息由消息头和消息体组成,消息头参考如下:
|
|
后记
由于个人水平有限,有什么不足与错误,敬请指正!
文章作者 沉风网事
上次更新 2016-07-29