IM场景下的系统拓扑及协议优化
技术领域中的一切事物都是人创造出来的,因而取决于特定时期的人所持有的价值观和目标
PS:去年12月份重构IM系统时的一张简易拓扑图.
A.系统拓扑
-
一个好的架构可以支撑多少同时在线用户?
-
单机C10K,C100K?
-
Scale out or up?
#1 第一层:接入
接入层机器在保证服务质量不受影响的情况下尽可能多的接入客户端连接,提高入口机使用率是一个永恒的主题.
技术备注:此前完全基于TCP现在我们改用websocket(当然底层依然还是TCP).
#2 第二层:路由
路由层机器存在的意义协助接口层机器消化用户接入状态(哪台机器接入的哪个用户?),同时解耦业务(按Channel分路由).
- 与接入层通过TCP建立高速路由通道(用mina还是netty看团队吧)
- 对网关开辟Http无状态接口,做到有所节制(这个直接用Servlet吧)
#3 第三层:网关
这部分是给其他业务系统开放Http接口,也为运营提供支撑(如:非法消息召回,运营消息推送)
最后,session信息存哪:redis集群?memcache集群?CouchDB? 选择最适合自己的就行.
技术的本质不分语言,用最适合自己团队的,合理的解决业务痛点,才是迫切需要的.
B.协议优化
App泛滥的今天,用户体验也随之上升几个层次,一步一卡的产品已销声匿迹. 伴随着技术的进步,物联网开始融入生活.打住!今天不说那么高大上的事物(水平有限),我想讲讲工作上遇到的一个问题,然后聊聊自己对技术的一个心态.
公司的一款App产品的即时通讯部分底层基于websocket协议:client与server通过一套自定义的上层协议进行消息互通.大致场景如下:
#场景1:冷启动到激活
- App启动与Server建立websocket连接
- App按channel向Server发送sync请求(询问有没有未读消息)
- Server返回各channel的未读消息状态(多少未读等)
- App按照返回的结果从server端拉取(pull)未读消息
- Server返回对应的消息,并告知是否还有更多
- App成功接收到拉取的消息之后,回调Server已成功收到哪些消息
- App拉取消息返回没有更多时则发起Active协议
- Server接收到Active之后将对应的Channel激活
……
#场景2:聊的热火朝天
A用户发消息给B
- A用户使用App发送一条消息到Server(转菊花)
- Server成功收到之后,告诉A用户发送成功(菊花停)
- Server解析消息中的receiver:B,然后向B投递消息
- B在线时,收到消息之后回调Server已成功接收.
理论上到第4步就可以表示消息已完成由A到B的一个过程,体验做的更好的一些App会反馈给A:B用户已送达,消息已读等.
哪些地方可以优化
- 批量提交
- 压缩协议
- 简化协议
说了这么多,那么问题来了?
存储交互的每条协议,按大小排序给出Top N.
关于这个问题,后面将陆续在Cassandra系列文章中作为案例一步步分析.