概述
- 使用Go语言打造支持,同时十万人在线的IM系统
- 系统单机支持十万人,如果分布式部署后,支持数百万都是可以的
- IM 系统, 即时通讯(Instant Messaging),比如说我们的微信,QQ 等
- IM 系统,它具备非常独特的几个特性
- 第一个特性,它本身是结合社交产品电商产品以及办公类产品的标配
- 第二个特性,我们的产品,它的技术含量非常高
- 打个比方,我们的微信群里面,每天可能没什么聊天的话语
- 但是突然之间因为一些突发事件,那整个微信群就数十条上百条聊天记录一下子就爆了
- 这时候对我们整个系统的应对突发事件的这个能力要求就非常高了
- 如果十分钟之内没有处理好这个事情,每个用户也感受到延迟非常严重
- 所以,IM是用户最能切身体会的一个产品,好不好用,很快就能鉴别出来
关于 IM
- IM 产品本身具备一定的技术含量
- 未来是5G的时代,互联网的时代,物联网的时代,AI的时代
- 这个时代要求我们人和人之间联网人和AI之间联网人和终端之间联网
- 人的一些指令,一些信息发送出去,比如说你的一个指令发给设备,怎么实时的发给这个设备呢?
- 人和人之间发括信息,怎么实时发送这个信息?这就是我们核心的一个技术,是就实时推踪技术
- 恰恰IM是整个实时推送技术的非常典型的一个代表,门槛也不高,业务场景人们也熟悉
实现IM的基本功能
- 实现我们的文字发送图片, 实现发送表情, 实现发送语音, 发送视频
- 语音和视频是我们应用中基本常用的一种交流的媒介了
- 如果基于h5来实现的,意味着可以移植到我们的浏览器,PC端,安卓和iOS系统里去
- 也可能有不同的业务,比如:支持红包,支持表单, 支持签到功能
- 在实现功能之后,自然而然就会进行到性能上的一个调优
性能调优
- IM的性能有几个关键性因素,一个是时效性,不能出现很大的延迟
- 第二个是很多人同时登录IM, 要具备并发的一个要求,
- 实现了基本的功能的问题,同时又解决了单机的性能问题,在这两个基础上,我们的应用已经是很优秀了
- 之后,就涉及到如何进行分布式的部署
前端技术栈
- html5:ajax/获取音频/websocket发送消息
- vue 制作单页app
- mui/css3等
后端技术
- 强大的websocket
- channel/goroutine
- template技术
系统架构
- 反向代理 Nginx
- 消息总线MQ/Redis
- 协议Udp/Http2的协议
整体流程时间安排
- 需求分析10%
- 重难点技术方案20%
- 功能实现60%
- 上线部署10%
需求分析
1 )基本需求
- 发送/接收消息
- 实现群聊
- 高并发 = 单机 + 分布式 + 弹性扩容
2 )需求拆分
2.1 实现功能界面
- 消息界面:发送人消息样式,我的消息样式,发送按钮面板相关功能等
- 好友列表界面
- 群聊界面
- 我的界面
2.2 实现资源标准化编码
- 资源信息采集并标准化,转化成content/url
- 资源编码,终极目标斗士拼接一个消息体 (JSON/xml)
- 资源标准化就是想尽办法想尽各种手段,将我们的本地资源转化成可以访问的资源
- 打个比方,我们输入文字, 通过输入框就可以获得我们这个可访问的资源了
- 如果输入一个图片,是什么样的一个流程?首先,点开我们的相册,选择这个图片
- 再发送到我们的服务器,服务器,再返回一个链接
- 这个链接就是我们资源标准化的一个结果,发送语音也是一样的
- 首先弹出这个语音按钮,录音以后,将获得的这个文件发送到服务器,转换成一个链接
- 我们拿到这个链接,这就是资源的标准化,那资源标准化以后就进入消息编码的阶段
- 拿到这个文字和语音图片的链接,将它们编码到一个消息中去
- 最后通过我们系统的一些api,发送到我们服务器服务器转发到我们群聊或者单聊的某一个人
- 整个过程文字首先转化成 content 存在到我们消息中去
- 表情包它本身要去提供了一个URL,它是一个双方已知的这样一个url
- 并不需要额外的再上传了,直接编码到我们消息里面去
- 我们的图片语音,它会首先被上传到服务器,再返回一个标准的URL,这个url可以被我们每个人访问了
- 这时候再把这个URL编码的我们消息中去
- 最后消息体通过API发送到我们系统,系统再转发给我们参与聊天的人或者群里的每一个人
- 这就是我们的资源标准化,并且实现编码的整个过程
2.3 确保消息体的可扩展性
- 消息体它本身一定需要兼容基础的媒介:URL/Pic/Content/Num
- 比如说图片,比如说文字,比如说语音,但是兼容了这些媒介往往是不够的
- 因为这个IM它的业务性非常强,将来肯定会扩张红包,签到,语音电话等
- 那这时就要求我们这个消息体的设计,应该兼容后续大量的新的业务场景
- 对新业务进行扩张的时候,不能对现有的业务产生影响
- 基于上面几点,我们这里提供一种可行的这种消息体的一个格式如下
- 这里只是一个举例,后续可以扩展
2.4 接收消息并解析显示
- 接收到消息体(Json)并进行解析
- 区分不同显示形式(图片/文字/语音)
- 界面显示出自己发和别人发的
2.5 群聊的特殊需求
- 基础功能上无区别,发送文字,语音,图片等
- 特殊性在于:一条消息由多个参与群聊的终端及时接收到
- 这意味着服务器压力,考虑服务器流量的计算
服务器负载分析
- A发送图片512K, 如果这个群有 100 人在线群人员同时接收到 512K * 100 = 50 M
- 如果系统里面有 1024个群,50M * 1024 = 50G
- 这样的流量是非常大的,一台服务器能抗住这个流量,是一个非常大的挑战
- 解决方案:
- 1 ) 使用缩略图 (51.2k) 提高单图下载和渲染速度
- 2 ) 资源分离,提高资源服务并发能力使用云服务(qos/alioss), 100 ms 以内,支持海量并发
- 3 )压缩消息体,发送文件路径而不是整个文件
2.6 高并发
- 单机并发性能最优
- 海量用户采用分布式部署
- 应对突发事件弹性扩容,云平台提供