本文原文内容来自InfoQ的技术分享,本次有修订、勘误和加工,感谢原作者的分享。
1、前言
自从2018年8月20日子弹短信在锤子发布会露面之后(详见《老罗最新发布了“子弹短信”这款IM,主打熟人社交能否对标微信?》),关于它的讨论不绝于耳,7 天融资 1.5 亿的传闻更是将它推到了风口浪尖(请见《[资讯] “子弹短信”发布一周即融得1.5亿资金》)。
同时很多技术人开始分析它的代码,挖出了它的 IM 系统其实不是自研,而是使用网易云信提供的第三方服务(即时通讯网注:其实子弹短信租用网易云信的SDK是共开的秘密,子弹短信官方并没有回避)。
有人质疑说,第三方的 SDK 做一个 demo 跑跑还可以,能拿来开发正式产品吗?其实,在实时通信领域,近年来的研发重点并不是即时通讯技术本身,而是由直播带火的实时音视频技术。随着 5G 的到来,WebRTC、SD-RTN、AV1 等新兴技术正在快速的发展当中。相对来说,即时通讯的技术已经比较成熟了,据了解,从子弹短信上线以来,到现在近 800 万激活用户,其服务一直保持稳定运行中。
子弹短信背后的网易云信即可作为一个研究的案例,本文内容来自对网易云信首席架构师周梁伟的采访,采访内容主要围绕网易云信这种海量用户IM云平台的关键技术难点以及对应的技术实践。
言归正传,我们往下看正经内容。。。
学习交流:
- 即时通讯开发交流3群:185926912[推荐]
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
(本文同步发布于:http://www.52im.net/thread-1961-1-1.html)
2、IM 开发当中的技术难点
周梁伟介绍,子弹短信目前主要使用网易云信的功能有:
1)即时通信的核心功能,比如 IM 的移动通信,包括图片、文件等等;
2)同时也使用了视频通话的功能,包括点对点,以及群聊形式的视频和语音通话。
在发布会的介绍中重点演示的语言转文字功能并非网易云信提供,据猜测应该使用的是锤子手机之前使用过的语音处理服务提供商科大讯飞提供的功能。
对于 IM,更关注的是社交产品用户体验层面的东西。具体来说就是怎么构建一个更好的沟通逻辑,更快速的帮助用户达到更好的沟通效果?这其实也是子弹短信瞬间能够火起来的重要原因。所以,IM 开发中的技术难点就在于对用户体验的追求。
首先:IM 核心关注点一是消息传输的速度要快,涉及延时方面的问题;第二个是要保证消息的送达率。同时,现在用户的设备多样化,IM 通常需要支持多设备,又涉及到一个多终端消息同步的问题。
其次:IM 产品的用户量和活跃度通常都很大,在一些特殊的时间点经常容易造成流量的波峰,因此技术上需要能够应对突发的量级。所以在前期需要设计好弹性扩容,对系统的伸缩能力提前做好设计。
最后:IM 包含用户的大量隐私,一旦被黑客攻破不堪设想,同时在公共安全方面的影响也越来越受重视,因此很多 IM 产品都投入精力做内容安全、平台可控方面的工作。
本节内容中,涉及IM消息送达保证方面的技术,请深入阅读以下文章:
《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》
涉及IM消息送达效率的资料,请深入阅读以下文章:
《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》
涉及IM高性能架构方面的资料,请深入阅读以下文章:
《一套海量在线用户的移动端IM架构设计实践分享(含详细图文)》
《腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面》
有关IM通信安全的资料,请深入阅读以下文章:
《传输层安全协议SSL/TLS的Java平台实现简介和Demo演示》
《理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)》
《微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解》
《来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享》
《即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了》
>> 更多同类文章 ……
3、IM 通信协议设计的考量
其实在上面没有提到一点,也是在 IM 中最为核心的一点,就是通信协议的开发。
在这方面,目前行业里有一些开源的方案如 XMPP、MQTT 等(MQTT请见《扫盲贴:认识MQTT通信协议》)。但是,这些开源的方案对后期产品的增长,用户量级的突发式爆增是非常不利的。
开源通信协议的劣势主要有几方面:
1)这些开源项目出现的较早,其实并没有考虑到移动互联网 2/3/4G 等复杂的网络情况,包括应对电信运营商在信令等方面的复杂设置;
2)目前鲜有对这些开源技术软件和服务把控度比较强的技术团队,难以进行源码级的扩展和修改,出现问题也难以及时解决;
3)商业化 IM 里消息的传递在过程中是否安全可控是非常核心的要求,如果使用一些标准的协议,就代表了这个东西是开放的,也就是说是有能够被破解的潜在风险,在企业服务场景里有些企业也因此而拒绝通信协议的开源。
有鉴于此,市面上注流的IM包括 QQ、微信等在内的,通信协议都是自研的。
▲ 市面上部分主流IM的通信协议(本图来自《史上最全即时通讯软件简史(精编大图版)[附件下载]》)
一个成熟的通信协议都是多年经验沉淀下来的,网易云信的 IM 服务并不是凭空产生,而是继承了之前网易泡泡、易信的技术。对于通信协议需要关注的地方,周梁伟介绍,云信的私有协议首先关注几个层面,一是安全性,也就是通信过程中所有数据序列化的算法、加密的机制,以及加密的级别,全都是自己定义的。同时也考虑到,在整个传输的过程中可能长期存在的安全风险,比方第三方的攻击,以及数据在网络流转过程中被拷贝和重放的潜在安全风险,这些在设计过程中都需要被规避掉。
第二个,因为现在即时通信更多的往移动互联网方向发展,用户的网络环境具有非常强的多变性,经常属于跨网和弱网的环境下,所以传输协议非常关注对消息的压缩,以及网络带宽的占用,网易云信在这方面也做了很多的工作。这也和标准协议有差别,标准协议的消息结构都是 JSON 或 XML 格式,承载同样的有效内容,最终呈现出来的消息体会变得非常庞大,但在这一块私有协议可以做得非常好。
还有一个很重要的方面是私有协议对扩展性的支持,传统的协议不能做到很好的扩展,或者做完扩展后整个消息会变得非常大。对私有协议来说,可以随时的做各种场景的定义、各种新协议的增加和各种版本的兼容。
其实目前业务主流IM,使用的私有协议格式基本都是基于Google开源的Protobuf(或者改进优化分支,比如微信就是基本Profobuf优化后的分支)。
有关Protobuf的文章,请深入阅读以下内容:
《强列建议将Protobuf作为你的即时通讯应用数据传输格式》
《全方位评测:Protobuf性能到底有没有比JSON快5倍?》
《金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(原理篇)》
《金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(实战篇)》
4、如何做到IM消息的高到达率和低延迟
对一个 IM 平台来说,到达率和即时性是两个核心功能点。对于消息传输机制的设计来说,首先设计的时候把 100% 的送达率作为一个核心要求,关键性的指标,要抱着必须要达到的态度来设计。
主要的技术手段是通过不同消息类型的相互组合来补充。
消息类型分为以下几种:
1)一种是在线消息:在线消息是指双方用户都处于实时在线的情况,在网络中实时送达;
2)另一个是离线消息:如果用户当时不在线,可能处于暂时离线的状态,我们把消息在缓存中存下来,缓存的消息可以保证更高的读取效率,用户下次上线的时候可以很快的取回来。
但仅仅靠在线和缓存是不够的,因为缓存可能会丢,网络可能出现会丢包,所以我们在数据库里储存关键消息。这类的消息是强一致性的要求,用户发送完成之后,服务端必须要确认数据被存入关键数据库里,否则客户端上的表现是消息未发送成功,是可以触发到上层去从事这种机制的。
存在数据库里的消息,用户可以在更长时间的离线以后实时同步,即使缓存里没有也可以拿到。另外还要考虑更长时间范畴的消息存储,应用的场景是什么呢?用户可能一个月以前开始使用这个 IM 产品,或者 1 年前使用了这个 IM 产品,现在更换手机了,更换手机以后消息如何在新手机上拿到?这种称为云端的历史消息(详见《浅谈移动端IM的多点登陆和消息漫游原理》)。
在所有消息的流转的过程中,这个消息到最后被存储在数据仓库里,数据仓库存储消息的时间维度可能是 1 年或者几年。在用户跨平台或者更换新设备之后,可以随时从云端再获取到这部分的消息。通过不同消息的相互组合之后,我们是可以达到消息 100% 送达的效果。
另外,从即时性的角度来说,现在的 IM 基本都采用长连接的方案作为消息实时送达的渠道。因为现在的移动设备对于 App 在后台的服务有限制,以前 Android 上还流行过后台保活、互相唤醒等等方式(请见《应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)》、《Android进程保活详解:一篇文章解决你的所有疑问》、《深入的聊聊Android消息推送这件小事》)。
不过,在 Android 系统的不断更新和手机厂商打压下,App 在后台的保活能力逐渐消失,现在基本都是接入各大推送平台,IM 消息即时性在 App 开发者这里能做的不多,主要看推送服务的实力了(Android高版本对后台保活越来越严格了,比如AndroidP的《Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》)。
5、IM 实时消息监控和分析
有一个以前人们不怎么提,但实际存在的问题,就是 IM 的合规。IM 是谣言等不良信息的高发地,在印度,WhatsApp 上谣言流传致使私刑案频发,到目前印度官方仍束手无策。
周梁伟介绍,IM 通信平台目前承载很多很重要的功能是传统运营商做的部分业务。以前我们用短信、电话,现在大家转移到即时通信的工具上,对监管层来说是有要求的。从平台角度来说,本身做的是一个消息通道的功能,消息就代表了会有舆论的传播,特别在群组或者聊天室这样参与者众多的状态下,所以舆论监管对平台来说是必须承担的责任,这是监管层面对平台运营方的要求。平台必须具备内容审核的能力,云信会按照开发者的配置把平台上产生的内容在云端保存起来,以备监管层随时做内容的审核。
同时在开发者 APP 运营的层面,内容运营或者内容审核、内容安全运营都是非常重要的范畴,目前网易云信和子弹短信在一起合作解决这样的问题。网易云信有一个专门的团队会负责内容审核的工作,包括会对所有的数据提取特征,会去做同步的、实时的内容审核,以及异步的内容审核,甚至涉及到机器学习的功能和人工介入审核的工作。
从技术层面来说,关于内容审核,目前用到产品上有两种场景,一种是同步审核,在消息发送过程中,这个消息就可以直接进入到内容审核系统里进行识别,如果识别出来有敏感词或者安全风险,会直接拦截掉。在第一时间避免消息的传播。还有一种内容,用户发的视频文件和非常大的图片,像这样的内容做实时审核会带来比较高的时间成本,这种情况下云信目前的做法是采用异步审核,消息投递出去了会进入审核系统,里面有机器算法的部分和人工审核的部分去进行鉴别,一旦审核出此消息违规,会触发 IM 消息撤回和删除的能力,避免风险的二次传播。
6、如何保证IM消息安全性
对 IM 来说,除了用户数据需要做安全防范外,还需要关注消息内容的安全,包括两个层面:
1)一个是:消息传输层面的安全,在传输过程中,通过协议和加密,以保证传输过程中的消息是不可逆的。恶意用户即使抓到网络传输的包也没有办法破译出来;
2)另一个:加密级别做到会话级别,是指一个用户的一次长链接行为,即使同一个用户多次登录,或者在不同时间点登录,加密的密钥都是不一样的。所以能够保证传输过程中是安全的。
第二个维度是,消息存储过程中是安全的,这里分为几个角度:
1)是对数据做自定义的序列化的方式,包括数据存储后,序列化或反序列化过程中的效率更高;
2)是如果泄露,是不可见、不可读的。另外,对于关键数据需要做加密,避免出现拖库之类的行为。
即时通讯网注:什么是黑客拖库?
拖库本来是数据库领域的术语,指从数据库中导出数据。到了黑客攻击泛滥的今天,它被用来指网站遭到入侵后,黑客窃取其数据库。
拖库可以通过数据库安全防护技术解决,数据库安全技术主要包括:数据库漏扫、数据库加密、数据库防火墙、数据脱敏、数据库安全审计系统。
另外,周梁伟表示,用户怎么使用云平台才能在过程中保证业务数据的安全,一般他们会建议,在使用平台的时候对业务数据做脱敏。比如说开发者自己的平台是用用户的手机号作为用户账号的,在云信里面注册用户的账号的时候,可以在业务层做一个关联。使用随机数或者随机的、无意义的字符串作为云平台数据库里的 ID,手机号的映射关系仅仅在业务方。通过这种脱敏保证数据的安全。
有关IM安全方面的文章,请深入阅读:
《即时通讯安全篇(一):正确地理解和使用Android端加密算法》
《即时通讯安全篇(四):实例分析Android中密钥硬编码的风险》
《即时通讯安全篇(五):对称加密技术在Android平台上的应用实践》
《传输层安全协议SSL/TLS的Java平台实现简介和Demo演示》
《理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)》
《微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解》
《来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享》
《Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)》
《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》
《即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了》
>> 更多同类文章 ……
7、本文小结
看完上面的内容,想必你对 IM 系统研发会遇到哪些问题,以及相应的解决方案有了大致的概念。当然这里只提到了其中的一些,还有其它方面,比如不同用户量级的系统需要不同的架构,QQ 在它的发展过程中就经历多次重构,感兴趣的可以继续阅读下面的文章。
《WhatsApp技术实践分享:32人工程团队创造的技术神话》
《王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等》
(本文同步发布于:http://www.52im.net/thread-1961-1-1.html)