在2014年12月19日~20日举行的ArchSummit北京2014大会上,腾讯即时通讯平台部技术总监范瑞彬做了题为《手机QQ的移动化实践之路》(幻灯片下载)的演讲,介绍了手机QQ在服务海量移动用户方面经历了的一些经验。

范瑞彬(hata fan),腾讯公司即时通讯平台部技术总监,T4专家。2004年加入腾讯,长期负责手机QQ后台整体建设,完整地经历了手机QQ从数千人在线到亿级在线的整个过程,见证了十多年来移动互联网服务的高速发展。目前主要负责QQ整体的接入平台建设,在海量分布式后台架构、IM系统设计、移动业务架构设计等方面积累了多年实践经验。

本文系根据演讲内容整理而成。

演讲主要涉及3个部分。第一,移动环境的特点。第二,针对移动环境的特点,如何做好接入?第三,架构设计理念方面的变化。

下图包含了云、管、端三个部分,多种终端通过多种网络访问云端的服务。上面红色部分是接入层,是首先会受到影响的。下面是逻辑存储、运营支撑和安全体系,这个系统目前终端同时在线过亿。终端每秒的请求量差不多千万,一天的请求量在数千亿的量级。

移动环境的特点

可以从三个方面看移动环境的特点。首先是移动网络,大家首先感觉是慢,而且流量又挺贵的。它还有很多种制式,差别也很大。还有终端的特点,相对PC来说手机终端资源(CPU、内存、电量等)是受限的,永远是不够用的。而且终端的平台很多,机型多,能力差异也非常大。还有一个很重要的特点就是移动性,可以随身携带,可以随时随地利用碎片化的时间,环境多变,使用频繁。

如何做好接入

面对这些环境的变化,接入首先会受到影响,而接入又是所有服务的基石。所以在移动环境下面,提供高质量的接入服务非常重要。如果将接入比作开车,那首先要选择一条快速的路线,这就相当于路由调度策略。另外还需要有一辆好车,车要快,类似于数据传输加速。然而选了一条好的路线,也有了一辆快车,并不代表就能快速到达目的地,尤其是非WIFI接入时,新增了基站、大量新增的网源系统,非常复杂。这里面有一些规则需要了解,如果不了解的话可能这些就是坑,而遇到了坑可能会翻车,所以不能把它当成黑盒,所以需要熟悉路况。路况很复杂,车也很复杂,跑的过程当中难免会遇到异常,所以还得会修车,不能抛锚,这几点是接入的几个主要工作。

1.路由调度(选快路)

分布式接入,在南方、北方和中部选择了三个地区,各自部署了一个点,每个点也覆盖了三大运营商,这是基础工作。

这时还有一个问题,如果中小运营商用户也访问到在三大运营商部署的服务,会存在跨网访问,质量很差。所以又建设了一个内容加速机房,它有独立IP,而且是TCP互联,路由直达,这样中小运营商的质量可以得到明显改善。针对海外用户,最初在香港部署了一个点,后来又在全球各大洲,每个洲选择了一个点,海外用户就近访问加速点,通过加速点再访问国内的服务器。

部署是在不断优化的,调度也需要更精准的体现。所谓调度,无非就是说什么时候,哪些用户该连到哪些server。所以这里可以分用户、server、时间三个维度。比如说用户,细化到每个网关;server,把用户调度到质量较高的server上面去;时间比较好理解,因为移动网络经常有波动,需要快速地发现波动,并及时自动干预,把它调度走。

还有一个很常见的问题,就是频繁切换网络。用户可能每天都在不同运营商,不同的网络之间来回切换。连接的时候不用域名,直接用IP,那如何保证用户不管怎么样切换网络,都能连接到连到他应该连接的server上面呢?假如说用户第一次连某个网络时,他会使用本地默认列表,连到server时,如果server发现不是最优的,会及时纠正,下发一份新的server列表。开发团队干脆把用户最近使用的50个接入点统统缓存下来。

2.数据传输加速(造快车)

做完了调度相当于选择了一条快速路线,这是不够的,还要想办法造一辆快的车。

首先是不用域名,直接用IP。这样可以减少域名解析的开销,更重要的是,可以避免域名解析带来的各种故障,还可以减少一些被屏蔽和封掉的可能。

第二点是重用连接、预连接。比如说QQ里面发图的时候,其实用户还在选择图片的时候,会先把连接建立起来,而且用户传完图以后连接不会立即断掉,会维持一段时间,后面有批量图的时候可以继续使用,减少一次连接的时间可以减少几百毫秒。

第三点是精简协议和逻辑。

第四点是参数调优。比如说“拥塞窗口”(congestion window,CWND),server的操作系统默认是4,建议调大一点,可以调到10,这样可以减轻慢启动对传输带来的影响。还有最大传输单元(Maximum Transmission Unit,MTU),之前跟运营商的朋友交流,他们给的建议是不要大于1400,现在基本上都是按照这个策略来做的。还有重新传输超时(Retransmission Timeout, RTO),一般设3秒左右,系统默认值设的是1。

还有一点叫高带宽时延积环境,在这种环境下面会遇到带宽吃不满,存在浪费的问题。以前网络都是2G网络的功能机时代。当时传图片大部分用的都是单连接。最近几年,网络越来越多,种类也越来越多,而且网络也越来越好。所以系统也进行了改进,可以根据网络状况动态地选择合适的连接数。比如说经过理论分析以及实验验证,开发团队发现其实在WIFI、3G、4G比较好的网络下面传输大数据时,用双连接比单连接提升至少10%,而且越好的网络提升效果越明显。

3.移动网络环境不是黑盒(熟路况)

不能简单地把移动网络环境当成黑核来处理,有些细节知识是需要了解的。

第一,要了解国内移动网关的一些设置,比如说它会限制某个包传输的大小,如果超过的话直接失败。之前跟设备厂商了解,华为很多网关设置的是10M,但是各家都不一样,也没有什么标准。还有网关很多时候对传输时间有限制,这个也是各家不一样的。了解了这些细节,肯定要很好地支持分片和断点续传,否则在某些地区可能会出问题。

第二,网关对很多标准的理解和实现,各家也是不一样的,尤其像影响比较大的,比如说对HTTP协议的理解和实现。比如说在HTTP的标准文档里面,提了一个range,但是没有强制去做,有的厂商支持的就不是太好。曾经遇到过一种情况,头部用到了range,在分片传输图片时,运营商网关把它过滤掉了,客户端就不知道下一次该从哪里发,所以可能又从第一片开始发,这种情况下,如果客户端没有做好相关保护,就非常危险,会大量的重传,用户流量会被大量消耗。这就是需要注意的地方,尽量不要在HTTP头部加一些字段,需要传一些信息的话,可以放在包体里面,自己解析和理解。

第三,tcp_tw_recycle。用户说网络是好的,但是连不上server。抓包分析发现,客户端三次握手的包已经发过来了,但是server没有回。这是什么问题呢?经过深入分析,研究了一下协议栈,以及一些参数设置,后来发现,假如tcp_tw_recycle是开启的,server会检查对端同一个网关IP发过来的包,时间是不是递增的,如果不是递增的可能会丢掉。但是移动网络环境下,这是很难保证的。关闭tcp_tw_recycle,问题就解决了。后来这成了外网接入层的标准配置。

第四,端口受限。有人反映某些地区的用户连server的某些端口连不上,或者是连接质量比较差。比如曾经发现香港数码通的用户连8080端口的质量非常差,很慢;还发现有些机场WIFI,比如说深圳机场WIFI,除了8080和43之外的断口都封掉了,用其他的端口用户也连不上。开发团队意识到,不应该被动地靠用户的反馈来发现问题和解决问题,所以建设了一套自动的系统,根据海量的数据去分析,根据分析结果,server在给客户端返回合适接入列表时,优先选择质量高的端口,而且也尽量注意端口搭配的多样性,这样可以提升接入质量。

最后看一下信令风暴。其实从09年开始,手机QQ这边每年会被运营商朋友拉过去一起探讨这个问题,双方本着互相理解、合作共赢的态度来对待这个问题。除了建立一些双方认可的虚拟消耗运算模型之外,双方还就移动业务达成了技术共识。比如说减少定时包,减少不必要的及时包,因为有些包真的不一定要非常及时。可以适当做一些缓存和合并。还有一点就是要有流控,万一客户端有BUG,大量的发包,这时候有压跨移动网络的可能,并不仅仅是数据网,它对电信网也有影响,所以server这时要有能力控制客户端发包的策略和频率,这样HTTP服务才能让人放心一点。

4.异常处理(会修车)

比如说业务用的是TCP长连接,但是请求有可能被劫持,可能会返回到奇怪的HTML页面,最常见的是WIFI的认证注册,这时需要及时准确地发现这些问题,展现出来提示用户。

有一种网络抖动叫先发后到,需要做一些保护。比如说要求客户端发包的时候一定要递增,而且即使进程被杀掉重新再起来,也要保证这次发包比上次大。借助这个大小能知道真实发包时间的先后顺序。

终端休眠,终端是为了省电,肯定有一些休眠策略,App为了应对这些策略,有一些自动唤醒机制,做一些自己想做的事。如果用Wakelock,拿到这个锁之后,系统再也进入不了休眠了,这个锁一般用两三秒就足够了,一定要慎重。

最后是App健康和智能检测。客户端不能保证百分之百不出问题,有时候确实有可能在一些小概率的情况下,存在异常的点,它有可能会触发一些频繁大量的发包策略。大量的发包会把用户的流量大量消耗掉,而且这还算轻的,更严重的是如果有较多用户都出现这样的问题,可能不是流量消耗的问题,而存在把移动网络压跨的可能,移动网络真的很脆弱。

《刑法》中有一条罪叫破坏通信罪,可以判三到七年,所以这种工作很危险,也是有责任的。压垮移动网络后果很严重,要想办法极早发现和干预。怎么办呢?server可以做一些准实时的流量消耗分析,如果发现在单位时间内用户流量超过某个异常值,就及时干预,而不是事后检查。比如可以把用户直接踢下线,或者更严重一点,直接让客户端的App自动自杀。

除了流量的问题,还有一些问题也是很隐蔽的,比如说用户的流量看起来没有太大变化。但是可能客户端有bug或者是设计不当,调用了几次后台操作,这个版本发出去的话,调用可能会增加好几倍甚至更多,后台的压力就非常大,于是又是过载保护,又是紧急扩容,这个也不是开发团队希望看到的,需要有更好的办法来解决它。比如可以分析这个版本,每个用户的使用频率。如果发现这个版本与上个版本相比,使用频率变化很大,多了很多,而且又没有提前报备,这里肯定有问题,就把这个问题抓出来,这些事情靠测试同学是不现实的,他很难测试到这些问题,这些问题需要技术同学自己想办法通过做智能数据分析来发现。

架构设计的理念

根据大量的实践,开发团队提炼出两个关键词:轻量交互和差异服务。

1.轻量交互

轻量交互,其实核心思想就是节省,主要思想是从协议层面以及逻辑层面做一些精简、合并、压缩、消峰、异步等等。

减少交互步骤。客户端一次请求,尽量把信息都拿下去,后台也尽量把相关的信息都加进去,完整地带下去,减少交互步骤。这里要求后台要多主动地做一些聚合工作,一些协议要重新设计。

精简交互信息,尽量减少每一次传输过程中的信息。有个原则,就是不用的信息尽量不要拉,这里要求开发团队在协议设计的时候要非常灵活和细致,要支持增量更新和同步逻辑。

复用包头。一般做协议设计的时候有包头和包体,包头里面放一些账号信息、身份凭证,还有版本信息。尤其随着现在安全压力越来越大,形势越来越严峻,身份凭证可能会越来越长。其实这些信息没必要每次都带,可以在接入server时做一些缓存,后面的包就不需要这些信息了,这样的话每个包可以减少几十个字节,甚至更可观。这样算起来收益是很大的,不光能帮用户省流量,因为传的内容烧,也能加快速度,对体验也有改善,勿以善小而不为。

智能合并压缩。这里需要对业务逻辑有深入的了解。不是所有的包一定要最快响应,可以请求分一下优先级,哪些是需要及时响应的,一定要及时保证。哪些是可以降级的,不需要很及时。可以把大量的不需要及时响应的包做一些延迟,这个延迟不仅是为了解决运营商的消耗问题,延迟以后可以做压缩。当然具体延迟多久,可能要根据具体业务的场景来看。

客户端异步削峰。还是细分问题,把一些不重要的包或者是当前这个不是立即需要的可以往后放,先让用户快点接入进来。同样,客户端也需要注意不要把UI绘制跟存储放在一个线程里面做,避免卡顿。

2.差异服务

可以把差异服务理解成个性化服务,针对网络情况和终端优化应用。下面具体看看。

怎么做好预拉取。比如说QQ会拉消息,拉过来的一堆消息里面可能有一些是图片消息,一开始看到这些图片消息只是缩略图。那何时去下载这些缩略图的原图呢?如果说等用户点了之后再去下载,自然大家会觉得这个很慢,体验不好。那提前下载该怎么做呢?这里要细致和全面一点。比如说可能要细分网络状况,在非WIFI网络下面流量是很贵的。如果把原图下载了下来,用户也不看,这样流量就浪费了,这浪费的就是钱,肯定不合适。那怎么办呢?可以设计一个算法,类似于银行家算法,给每个用户分配一个配额。比如说有500K的配额,预拉取一张原图,比如100K,如果用户看了原图,配额不变;如果用户后来并没有看,则把配额减去100K,凡是预拉取了而不看的配额都减掉,配额减到零就不会再做预拉取了,避免盲目下载造成大量的流量消耗。

在WIFI情况下,是不是可以简单地全下载下来呢?这样也不好。虽然用户的流量在WIFI下基本不收费,但是腾讯后台的出口带宽很贵。尤其是图片下载消耗非常大,这个钱是很多的。怎么办呢?可以根据业务场景做细分。比如把图片分为群图和C2C图,就是好友之间点对点的图。分析发现,C2C图相对是比较重要的,用户点看原图的概率非常大。同时C2C图占比相对来说又是非常小的,因为大部分是群图。所以C2C图可以预拉取。群图还是采用类似于银行家算法的方式进行管控。

预拉取思路很简单,但是要做好,可能还需要很细致地结合网络状况,结合用户状况和业务场景做细致全面的细分,这样才能在用户体验,以及服务成本和用户成本之间找到一个恰当的平衡。

信息繁简不一。很多信息应该分类归档,针对一些好终端、好网络,尽量返回一次很好的信息,反之只给它简化版。

多种套图规格。需要根据多种屏幕来抽象和简化出几种通用的图片规格,而且可以根据不同网络状况来定每种规格的压缩率。

终端是该轻还是重。到了手机时代,因为手机本身能力比较弱,而且产品还经常要求做一些跨终端的一致体验,很多东西必须放在云端统一处理才可以。大部分场景下是轻终端重后台,具体要看业务场景。比如说有些游戏,以前PC时代为了防止PC客户端作弊,很多信息都是客户端直接给server,一律由server统一去算。但是在手机游戏上面,为了减少信息传递以及减少交互次数,很可能会在终端也做适当的计算,把计算结果再发给server,在这种特殊的场景下面,在这些逻辑方面可能终端做的更重一些。所以这个问题有普遍性,也有特殊性,要具体分析、具体看,深入理解业务场景和逻辑。

能不差异的地方就不差异,考虑全面些。设计的时候要考虑全面,要把各种平台、各种网络都考虑到。在选择压缩算法、加密算法、图片格式和文件格式时,这些东西能通用的还是尽量通用,不要给自己找麻烦。如果有些地方没法统一,必须要差异,这里要抽象简化,简化为几大类,而且这个差异点尽量使后台可调可控。

终端版本信息管理,终端运营配置管理。需要把终端版本的各种信息记录下来,然后才可以根据这些信息,再加上用户的信息灵活调整配置给不同用户更好的体验。可以根据不同地区、不同网络、不同版本、不同运营商和不同号码,以及根据不同的CPU、不同的摄象头、不同的内存,给用户下发不同的闪屏和不同的插件,这是基础能力的建设。

范瑞彬最后还用一句话做了总结:“从实践中来,到实践中去”。

转自 http://www.infoq.com/cn/news/2014/12/qq-mobile-practice?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global

时间:2014-12-24 08:48来源:InfoQ 作者:臧秀涛 责任编辑:zhangkai

手机QQ的移动化实践之路相关推荐

  1. 腾讯手机QQ团队无障碍化探索的曲折与收获

    大家下午好,我是来自腾讯SNG即通产品部手机QQ项目管理Alice. 大家都知道,在中国有1700多万的视障群体,他们通常从事推拿.公益等工作,为社会创造价值. 手机QQ在接触这样一个群体,在和他们沟 ...

  2. 京东微信、手机QQ引领社交化购物趋势

    2019独角兽企业重金招聘Python工程师标准>>> 京东微信手机QQ购物,就是将电子商务平台接入微信和手机 QQ 等社交平台的购物模式.目前,在微信,京东有一级入口"购 ...

  3. Android手机QQ的UI自动化实践

    UI自动化 我们为什么要搞UI自动化 可能很多同学都有疑问:我们写了这么多单元测试,为什么还需要UI自动化测试呢? 按照测试金字塔理论,其实每种类型的测试都有自己的意义,UI自动化的意义就在于更贴近用 ...

  4. Android手机QQ的UI自动化实践,音视频服务器开发难点

    在上一步环节中,我们虽然确定了自动化框架,但是框架只提供底层的驱动能力,如果无统一封装模式进行规范,随着用例的增多会变得难以维护,所以我们需要一个统一模式来封装细节,可以使 testcase 更稳健, ...

  5. Android手机QQ的UI自动化实践,为什么spring能最好地改变Android

    按照部门的要求,我们本次的自动化需要用到同源(同语言同工程)的形式,而且针对手Q很多复杂的场景,我们需要稳定复现,所以我们排除了QTA.Appium.AirTest等框架,最终选择了UiAutomat ...

  6. Android手机QQ的UI自动化实践,死磕原理

    我们的痛点是,需要快速铺量,那按照用例场景,所见即所得的代码方式,的确是很快,但是我们需要对该模式规范化.结合测试用例的3A原则(Arrange.Act.Assert),我们创造了一种新的封装模式QT ...

  7. CI Weekly #9 | 揭秘阿里 Docker 化实践之路

    2017年悄然而至,对 flow.ci 你有什么新的期待呢?新的一年,flow.ci会越来越强大好用,希望继续得到你的支持与反馈.最近,我们做了如下的「功能优化」与「问题修复」,看看有没有你想要的: ...

  8. android测试qq,Android平台手机QQ和360手机卫士测试

    Android平台手机QQ和360手机卫士测试 Android平台手机QQ和360手机卫士测试 目前最热的Android手机平台,使用豌豆荚手机精灵完成最新版安装后,对两者的运行兼容情况进行了详细的体 ...

  9. 有种速度让你望尘莫及 | 手机QQ及Qzone速度优化实践

    导语 移动互联网发展那么快,运维技术也要适应业务的变化啊,这次小编找了腾讯牛人介绍的手机QQ和手机Qzone的速度优化实践. 我们坚信不同垂直领域的运维分工会越来越不同,如何能在不同的业务形态上,利用 ...

最新文章

  1. 导航选中后标记的样式实现滑动效果
  2. @总结 - 4@ 多项式的多点求值与快速插值
  3. 软件工程概论 课堂练习 第3次作业1【结构化系统分析——交通违章处理】
  4. 如何使用SSL pinning来使你的iOS APP更加安全
  5. 03-instancing 工程分析详解
  6. C语言隐式/显式类型转换 | C++四种强制类型转换、类的隐式转换、explicit
  7. 转载 树莓派vnc 教程
  8. MUI开发指南(二) webview对象
  9. NGINX 笔记 - GeoIP 限制策略配置
  10. 软件测试基础知识整理
  11. 小白学电脑计算机的组成,新手学电脑步骤,从零开始学电脑
  12. Flink服务的HA配置
  13. 愚见《Nighttime Visibility Enhancement by Increasing the Dynamic Range andSuppression of Light Effects》
  14. Excel自动生成条码工具
  15. Solidity 基础(一)
  16. linux设置开机自启某个命令
  17. idea创建文件时生成文档注释
  18. IDL图像可视化(八)
  19. 齿轮振动信号的数字滤波处理-Matlab源代码
  20. 手把手教你用C写游程编码

热门文章

  1. uniapp引入外链
  2. python大气校正_Python调用C2RCC实现批量数据的大气校正
  3. YDOOK: Python3 IPC 进程间通信方法分类总结
  4. CE系列交换机堆叠配置
  5. 淘宝高价卖假鞋的黑店名录(商城篇*未处理篇)
  6. 待办清单和日程计划表哪个会更好?可做日程表和待办提醒管理的便签
  7. 对rose框架的简单使用
  8. 骇客教学_大数据。 大骇客。 大云。 你准备好2016年吗?
  9. VirtuaNES.v0.97源码探究6 内存相关
  10. 201521123055 结对编程作业