我在QQ邮箱的这四年
最近几天在公司内部广受传阅的一份广研同事的工作总结分享,很不错。特转一下,文字版权归kenbin所有。
(一)
恍惚间已经工作了四年有余,很幸运刚毕业就遇到一个很好的锻炼机会,05年7月份刚成立的腾讯广州研发中心,主要负责腾讯的邮箱业务,我是在06年2月份加入到这个团队,也算是见证了QQ邮箱的整段发展经历。有些记忆隔的太久,可能时间和细节上不太准确,尽量去回忆吧。
写这个系列的文章也是对自己过去四年工作的一次回顾和总结,我会结合自己的经历和感受来写,视角不会太开阔,用平铺直叙的方式吧,就像讲故事,我是一个没有太多故事但却喜欢讲故事的人:)
也许大家都听说过腾讯做邮箱的那段往事吧,创业团队太自信了,觉得把邮箱放到客户端上依赖QQ巨大的用户量自然就会成功,但是结果却恰恰相反,纠正错误认识,在04年紧急做了QQ邮箱的web版,也就是QQMail2.0版本,这个版本明显过于仓促,和网易等其他邮箱应用相比,差距很大。腾讯在05年中旬收购了foxmail及其团队,成立了广州研发团队,主要负责QQ邮箱的开发和运营。很明显,公司非常重视邮件这块业务,也基本承认了之前的判断错误,所以打算下大力气做好邮箱业务,这为之后QQ邮箱能够取得优异成绩奠定了政策基调。
在计算机软件领域,一款成功的产品背后一般都会有一个明星人物,QQ邮箱也不例外。QQ邮箱的这个关键人物大家应该也有所闻,他就是foxmail的作者张小龙。09年赖勇浩同学在一次技术交流中谈过他心目中的几个国内顶尖程序员和其成功的软件作品,有求伯君和wps,有鲍岳桥和ucdos3,有王江民和kv100,有梁肇新和超级解霸3,有张小龙和foxmail,有侯延堂和flashget等等。小龙被认为是国内第二代程序员中的领军人物,他曾经是国内顶尖的程序员,然而他在QQ邮箱的整个发展过程中不是以技术人员的身份在指导,如果要用一个最合适的身份来形容他,我觉得是产品经理。小龙曾经在内部发表过一篇文章,这篇文章讲述了他对互联网团队管理的一些观点,他认为互联网团队中的管理不是管人,而是管理产品体验,以产品体验为核心,产品设计和开发人员与产品共同提升,共同进步。小龙之于QQ邮箱的影响正如乔布斯之于苹果的影响。
QQ邮箱3.0版应该是广研自主研发的第一款邮箱产品,2.3版是从总部继承过来的,3.0版的后台很多代码也是从2.3版继承过来的。3.0版的UI有点像hotmail和outlook的综合体,思路很明显,把邮件客户端做到web上面,做一个富客户端的邮件应用服务。当时国内的邮件应用第一梯队是网易和雅虎中国(中国雅虎是之后的事情),第二梯队的是新浪、搜狐、tom在线、21cn等门户,第三梯队是一些独立的邮件服务商。当时大家经常上艾瑞网看排名,QQ邮箱当时排名在12左右,还进入不了前三梯队,市占率低到可以忽略。当时的目标是在一两年内进入第二梯队,我想,如果当时确定目标是超越网易成为国内第一,估计是没人相信的,包括我们自己。
3.0版是广研的处女作,投入了全部的人力物力,采用了当时业界最先进的技术方案和最好的UI设计,并且创新的采用outlook的三栏结构,很像邮件客户端,这是一次软件服务化的尝试。
我是06年2月份加入广研,当时3.0已经渡过了最繁忙的开发阶段,进入了小范围的公测阶段,用户可以在2.3版和3.0版之间切换。3.0版的集中开发大概是半年多时间,05年中旬广研招兵买马的时候,大部分人没有邮箱产品的相关开发经验,当时是在摸索中前进。然而,当时的团队却采用了业界最先进的ajax技术架构,当时的javascript代码有很重的面向对象的味道,用传统的软件工程思想构建了整个web框架,从软件的开发流程来说,这并没有什么问题,但是产品却有很大的问题出现了--慢,不是一般的慢,当时除了较快的电信网用户可以登陆进邮箱之外,其他的用户基本上都被卡在登陆上。06年的大部分时间,整个团队都在解决速度慢的问题,尝试了很多方法,把js容量压缩掉了一半,js混淆之后又压缩了很多,js文件分开为多个,但始终没有根本的转变,速度的提升仍然不能被用户接受。现在回过头分析这个问题,我觉得物理上的压缩和分割js文件之所以解决不了问题是因为问题的根本在于js的逻辑架构上,当时的js有明显的基类和继承类结构体系,这种结构并不适合物理上的分割,即使分割开,渲染消耗的时间是节省不下来的。
3.0版的后台基本上是继承的代码和开源代码的综合。最重要的邮件投递模块采用的是当时最好的投递引擎postfix,web端采用的是apache。邮件存储是简单的单文件存储方式,用户数据存储也是比较简单的,帐号和邮件列表是合并存储在一起的。这个架构对于支撑当时的用户规模是足够的。
06年之前广研在做QQ邮箱开发和运营的人数是比较少的,所以06年吸纳了不少的毕业生,我就是第一批广研接收毕业生中的一员,当时3.0版的主要开发人员集中在两个小组:QQMail小组和系统架构组,从名字上看,应该是QQMail小组负责产品层面的开发,系统架构组负责后台架构的研究和开发,不过我当时感觉两个组差别并不大,都是在做产品开发,都同时做前台后台,可能是人手紧张的缘故吧。QQMail小组除了做产品开发之外,还负责产品的运营工作,人数上稍微多一些。我加入的是QQMail小组,最初是以实习生身份参与到3.0的开发中,工作任务比较杂,写一些cgi,做一些内部系统和统计的工作,其余的大部分时间是在读代码,也就是上面提到的那些js代码,后台代码和cgi的代码。这近三个月时间是我有史以来精力最旺盛的一个阶段了,把所有的代码梳理了一次,写了好几本笔记,现在回忆起来觉得真是太不可思议了。
在我进组之后,当时的3.0已经过了集中开发阶段,开始进入优化阶段,对运营质量提出了更高的要求,当时整个QQ邮箱的运营只有一个粗糙的数据统计系统和一个nagios系统,数据的收集和统计的方法比较简单,cgi写日志然后收集起来之后再运用shell统计入库,甚至数据的页面表现也是shell做的。老大(leader)为我安排了一位导师,我跟着导师边熟悉系统边做一些数据统计方面的尝试,偶尔也会写一些产品cgi。这位做我导师的同事很有耐心,尤其是面对我这种打破沙锅问到底类型的学生,他在最初给了我最多的帮助,没有他的帮助,我不太可能在3个月理清整个QQ邮箱的架构,他解答不了的问题,会推荐更合适的同事给我,不过我比较取巧,遇到这种情况一般就去问老大了:)也正是在这些和老大的问答过程中,增加了彼此的了解,这为以后老大能够不失时机的给我最恰当的尝试机会奠定了基础,不过最重要的还是老大的信任。
跟着导师先后做了运营监控系统和一些相关的统计系统之后,老大给了我第一个机会独立完成一个系统,那就是广研的业务数据系统,这个系统包括数据的收集、整理分析、报表展示和数据波动报警等功能,至今仍然在使用,后台架构也基本没有什么改变,我在做这个系统的过程中,熟练掌握了两门新的语言:shell和python,熟练的程度足够我运用任何一门语言做整一个系统。shell帮我在数据收集的自动化方面做到炉火纯青,收集、纠错和报警一条龙,而且代码相当干净,值得反复阅读(请允许我陶醉一下);python是一门我非常喜欢的编程语言,让我痴迷了2年,甚至在去年还阅读了一些剖析python源码的书籍,我主要用python做内部系统的表现网站,报表、图标、趋势图无所不能,而我最满意的是用python设计实现了一个轻量的模板语言,这个语言帮助我通过简单的配置就可以做出一个统计页面的表现和数据提取,非常方便,现在还有同事在使用这个模板语言,代码也是相当干净(我又陶醉了)。
一个合格的程序员不会满足于做重复的事情,虽然后续接了不少的内部系统开发,本来都是可以简单的拷贝前一个系统修改一下就了事的,不过我把每一个系统都做的不一样,每个系统都要有至少一个新亮点,老大后来觉得我有点过于埋醉于技术疏于组织方面的锻炼是有证据的。不过老大还是很信任我,陆续又让我参与到产品层面的开发中,这次我又几乎独立完成了QQ邮箱的自助服务系统,包括faq及其查询、最近登陆记录查询、最近收发信查询和最近删信查询等若干辅助用户查询的功能。这是我首次做后台服务,后来这个服务相当稳定,其后台就成为了发信状态查询的后台,现在仍然在运转着。也正是由于这个发信状态查询服务的成绩,我被调去参与新产品的开发,虽然那个服务是我自己认为做的最差的一个服务,但是却有很大的意义。这也验证了互联网开发是结果驱动而非过程驱动的一个实证。
虽然06年的我得到了很多的锻炼的机会,做出了一些成绩,但是QQ邮箱这个时候仍然徘徊在速度和功能的博弈中,当时公司内部在进行hummer计划,广研这边除了QQ邮箱之外,要另外做一个hummermail,架构组为此把后台的架构进行了一次彻底的重构,把用户数据存储模块做成了一个通用性更好的存储服务,事实证明,这个存储服务成为了广研最核心的一个服务,支撑着绝大多数体验的数据存储;把帐号信息独立出来做成一个新的帐号系统;由于新邮件提醒的重要性,特别为邮件提醒做了一套后台,实现实时稳定的邮件提醒功能。这次重构虽然没能挽救3.0的失败和hummermail的流产(后话了),但是却成为全新版本QQ邮箱的最核心后台,相当了不起的一次重构,足以载入史册。
(二)
06年末看艾瑞网的排名,QQ邮箱在7、8名徘徊,进入了邮箱的第三梯队,但始终不能再进一步。
当时正在开发的hummermail让我们感到了一丝希望,这个邮箱比起3.0精简了很多,很像gmail的风格,我特别喜欢hummermail的UI。hummermail的后台已经是重构之后的全新系统,扩展性和稳定性都提升不少,前台也是重写的,整体给人比较简洁的感觉。但是随着公司在hummer战略上的转变,hummermail最终没能与用户见面,胎死腹中,不过当时的hummermail遗留的问题很多,所以并没有感到多么的遗憾。重点依然是3.0版,在06年末的时候,2.3版宣告结束寿命,全部的用户升级到3.0版,3.0成为QQ邮箱的正式版。这个时候我正在做自助服务系统,当时正困扰于不同版本之间的切换逻辑,突然间这个问题就不存在了,省掉了很多的糨糊代码。我也参与了2.3到3.0的切换项目,当时考虑的很周详,甚至做好了随时回退的策略。不过最终切换是很顺利的,只有一小部分用户投诉不能再进入2.3版本,觉得3.0太慢无法使用。
全面切换之后,速度问题成为一个关键点,记得当时开了一个很大的头脑风暴会议,所有开发人员都参加了,大家脑暴提速的方案。当时提出了一堆影响速度的原因,针对这些原因陆续做了很多测速数据统计。当时着手解决速度问题是从几个方面开始的,首先仍然是对js进行压缩和分割,并且逻辑上也进行优化,能够异步加载的尽量异步加载;其次是更换了apache,换用公司内部研发的webserver,效率有相当大的提升,原理上是把静态的cgi编译成为动态的cgi,这样请求不需要重复加载cgi,进程资源可以重复使用,这需要改变一下cgi的开发方式,但提升的效率很明显;后台服务也做了许多cache模块,最大化可以缓存的数据。这几条做下来之后,很残忍的结果,速度提升有限,仍然没有根本改变速度问题,而当时的重点也开始转移到做新功能上,不过留了一线余地,当时成立了一个虚拟小组,打算对那些速度特别慢的用户提供一个最简单的版本,只有html,没有复杂的js逻辑,看上去这是多么平常的一个决定,却在数月之后让QQ邮箱经历了一次涅磐之旅。
在UI上,本着简单至上的原则,重新设计了QQ邮箱html版,或者叫做简洁版。大家可以把皮肤切换成默认的那个蓝白底色,那就是QQ邮箱简洁版的鼻祖了。当时这个版本比起hummermail版本更加简洁,前端的表现也是非常简单,没有太多的js逻辑,我当时感觉简单的有点单薄了,不过却解决了一个核心问题--速度,简洁版的速度有质的提升,上升到当时最快的邮箱之一。简洁版刚一上线,最多的好评不是来自用户,而是来自于公司内部员工,好评如潮的程度,因为当时的策略很谨慎,依然是放量了小部分的用户,不过我又要在自助服务中做3.0和简洁版的切换逻辑:(
当时的局面是,公司内部对简洁版好评如潮,外面的用户对3.0平淡无奇。于是当时老大们做了一个至今仍然心有余悸的决定:把3.0下线,全部用户切换到简洁版。我当时的第一感觉,这太疯狂了,2.3到3.0的切换用了一年半时间,3.0到简洁版的切换用了不到两个月时间。当时有些3.0的开发人员伤心的留下了泪水,那是多少人的心血呀。但是事实证明,这是一个相当正确的决定。至此,QQ邮箱完成了历史上最华丽的一次升级,一次涅磐的欲火重生。当时QQ邮箱的口号是:快速、稳定和简洁。大家一致认为邮箱的核心是快速稳定的收发信体验,不是什么其他华丽的功能,速度和稳定性是邮箱的生命线,而简洁是诠释快速和稳定的一个注脚。
至此开始,歌舞升平,QQ邮箱进入了快速的上升通道。很快从艾瑞网的数据上反映出来,我们已经在短短的几个月内稳居国内前五了,但游戏才刚刚启动,真正的精彩从此刻开始。
然而,3.0的故事并没有结束。3.0结束之后,团队进行了全面的总结,对整个2.3到3.0到简洁版的开发过程进行回顾和理论升华,小龙对整个3.0的得失作了一个很经典的总结:七星级的服务要七星级的团队铸就,当我们还是三星级的团队,那么我们就努力做好三星级的服务。3.0版过度使用了ajax等最新的技术,这些技术并不是当时团队的拿手活,使用的过程中偏于理想化,虽然之后就产生的问题做了许多优化,但效果不明显。而html版废弃了3.0的那套前端代码,js只处理最简单的逻辑,加上后台的重构效果明显,邮箱的速度体验提升显著。
html版上线之后,为了更好的保证速度和稳定性,运营上非常重视相关的数据监控和统计指标,尤其是速度和邮件的投递成功率。针对邮件的投递成功率,我做了一个邮件追踪系统,这个系统可以查询到系统内每一封邮件的来龙去脉,并且定期输出投递成功率和失败率的统计报表,对较大的数据异常会报警处理,这份数据报表之后很被重视,每一次数据波动都会引起很大的关注,每次出现波动都会彻查每一个相关模块,在最短的时间内把问题解决。对于速度的监控,不仅监控后台的数据传输和处理时间,也对前端的用户请求时间进行监控,也会定期输出统计报表,相关应急措施也很完备。从这里可以看出,团队是切实地把快速稳定作为了邮箱的生命线。
为了更好的满足后续的产品开发和运营,对团队的内部组织进行了一次重构,因为敏捷的需要。说到敏捷,有件很搞笑的事情,公司内部很早就在提敏捷开发,但是我们有好多人在很长一段时间并不知道敏捷具体是指什么,后来公司说QQ邮箱是一个非常成功的敏捷团队,我们好多同事才开始去看一些敏捷相关的书籍。但是看了书本之后发现我们也并没有完全按照敏捷的具体形式在执行,对敏捷还是模棱两可的感觉,直到我们按照真正的敏捷运转了更长的时间之后,对敏捷才有了更深的体会,经常有同事说自己被敏捷了。我自己的体会是,无论敏捷是什么都不重要,重要的是理论结合实际,在实践中有切实的指导意义,团队产生了效率,结果显著,那就是好的方法,管它叫做敏捷抑或是其他什么。虽然有同事说我们很土,但是只要实用,土又有何惧?
外界有人觉得QQ邮箱团队很神秘,可能会认为QQ邮箱在敏捷方面有什么独到的秘招。其实我们运用的敏捷方法和大部分人运用的方法差不多,甚至我们还要土一些,但是值得一提的是,我们在敏捷的过程中不断去提炼和优化,不断的摸索出适合自己的路数,当我们在敏捷方面的认识只有三星级,那么就只做三星级的敏捷迭代。
(三)
从07年下半年开始,QQ邮箱围绕着快速稳定的核心体验,本着团队与产品一起成长的思路,以周期的敏捷迭代过程,一步一步向着目标迈进。当时所有的广研人都有一个梦想,那就是当我们的团队和产品达到七星级水平的时候,我们就可以享受一下迪拜帆船酒店的七星级服务(07-09年,我们已经体验了无数的四星五星级酒店了~)。
团队的成长离不开个人的成长,07年下半年到08年下半年这段时间,伴随着QQ邮箱的一个个令人惊喜不断的新功能,团队的成员也都在各自的领域齐头并进,跟随着产品一起进步。从团队和产品的发展历程中,我学到一点,那就是做任何事情要掂量好自己的水平,量体裁衣,根据自己的实际情况寻求个人的发展,07年,我觉得自己最适合做的事情就是把程序写好,所以那年读了许多编程相关的书籍,其中有一本书影响了之后的程序生涯--《UNIX程序设计艺术》--这是一本绝好的洗脑圣经,这是一本关于kiss(keep it simple,stupid)的书,也是一本关于unix哲学的书。之所以这本书对自己的影响那么大,是因为读这本书的时机很恰当,在这之前,两年多的linux下编程经历,形成了很多零碎的经验,有些道理明白却总是说不清,这本书不仅帮我把知识整理成系统的体系,而且把粗糙的认识上升到一定的理论高度,让我能够在之后的程序设计中举一反三,有一套行之有效的方法论作为问题分析的工具。
这个时候的QQ邮箱团队,组织架构经过调整,职责更加清晰,团队也尽量发掘每个成员的特点,每个人都有机会展现自己的风采,在各自的领域做精做细。团队也提供了一些发掘个人潜在能力的机会,当时曾经尝试把开发人员轮流调配做一段时间的运营工作以提升大家的产品运营意识,记得当时小龙还布置过产品设计方面的家庭作业给一些开发人员,我也写过,这些锻炼的机会对于每个人来说都是难得的。团队也会根据每个人的特点,给与调岗的机会,08年7月份,我从主要负责运营开发的工作调岗到专职产品开发,对我来说,这是一次难得的职业转变,它使得我更加全面的认识自己,更好的发现和改进自己不足的地方。
07-08这段时间团队一直很稳定,团队的规模和我入职的时候相比变化不大,但是麻雀虽小,五脏俱全,除了产品、运营、开发、测试等主要的敏捷团队之外,还在这些基本团队之上灵活的组建虚拟小组,这些虚拟小组是按照产品特性分布,一个人身兼数职是比较常见的情况,需求多、人员少,这是适应当时情况的敏捷方式。由于我们把速度和稳定性也当作需求,所以也成立了专门负责速度和稳定性相关需求的虚拟小组,这个小组横跨了运营、开发、产品和测试,运营上细化相关的数据监控和统计,开发上根据发现的问题寻求解决方案,产品对业务数据进行分析总结再指导后续的滚动,测试把关,确保速度和稳定性不断的提升。后台方面,当时广研社招来一个牛人S君,前面提到过,我们最初的邮件投递服务使用的是开源的postfix,虽然这个系统相当稳定和高效,但却并不能满足我们的需要,当时S君加入广研之后的第一个项目就是开发自己的投递服务,这个服务从开发到彻底替换掉postfix用了很长一段时间,不过投递服务相比postfix更好的融入到QQ邮箱的架构中去,而且效率有很大的提升,自主的东西灵活性很强,当时切换投递服务是小心谨慎的,因为这块涉及邮件最基础的收发信体验,无论如何不能有丢信,这是邮箱生命的生命。我想,参与切换服务的同事一定从中积累下相当丰富的经验,这些经验对以后的服务升级是相当有价值的。这次服务升级为邮箱的速度和稳定性奠定了又一个扎实的基础,系统内部的所有关键模块都已经替换上了自主研发的组件,整个QQ邮箱的架构已经真正掌握在我们自己手里,意义很重大。至此,QQ邮箱形成了完全自主的核心平台,这为功能的快速迭代打了一剂强心针。
后台方面的另外一个重大升级是关于邮件存储的,之前提到过3.0版的邮件存储是继承了2.3版的简单的单文件存储方式,一方面读写的效率不是最优,另一方面占用的存储较大,随着业务量的增长,不做去重的邮件存储是无法接受的。但是我们并没有自己去改造邮件存储服务,而是和公司内兄弟部门合作,把邮件接入公司统一的存储平台,这又是一个庞大的工程,迁移的成本相当高,和投递服务的切换类似,这个数据迁移的过程也是分阶段逐步完成的,但是由于存储平台刚刚搭建好,不够稳定,发现经常读写超时,这会间接造成丢信,影响到用户的核心体验,广研这边立即启动了一个本地存储项目,当统一存储读写效率下降的时候切换到本地的高速存储,保证用户快速和稳定的收发信体验。这个项目也经历了很长一段时间,从这两次的后台切换和迁移过程来看,为了保证系统的稳定和用户访问的速度,一个看似简单的任务也会触发相当多的问题,如果没有相关经验,做好这件事情是相当不容易的,尤其是当用户的规模有数量级上的提升之后。
08年中期,QQ邮箱的后台已经实现了完全的自主研发和自主控制,但仅仅有这些后台的技术方案支撑还是远远不够的。有句话说,web2.0的产品是运营出来的。没错,QQ邮箱能够保证快速稳定的体验,能够保持敏捷的快速功能迭代,是因为这背后有一个强大的运营团队。运营是一个大范畴,它又可以分为几个部分:反垃圾、运维、数据分析和互通,而每一个部分都需要有一个方便高效的操作平台。我在07年下半年和08年上半年差不多一个月就会做出一个内部系统,后来开发出了模板语言之后,三天就可以设计开发一个系统。这就出现了一个问题,这么多的系统怎么使用,有时候产品做一个报表要同时上几个系统内搜集,他们找不到肯定要找平台的开发人员,那段时间说实话,我被搞得脾气都变得火爆了一些,一个相同的问题要回答无数遍。一定要整合所有的系统。不仅我这样想,老大也是这样想的,我当时的老大T君在看了其他兄弟部门的运维平台之后很受刺激,当时想让我和其他几个同事去兄弟部门取经,甚至老大连请吃饭套近乎的招都想到了。然而我最终没能完成这个任务,因为在08年7月份,我被小龙调配到产品开发一线,从事一个全新的产品--阅读空间--的开发。我的老大也换成了H君,这是我第一次面临职位变迁,我当时没什么特别的感觉,无论是与T老大,H老大还是小龙的谈话中,我都是抱着一种无所谓的态度,感觉无论在哪里做,做什么都不重要,因为我追求的是完美完成任务,体验过程和钻研技术,其他的没想太多。但是一年多的经历之后,我因为这种错误的认识饱尝了巨大的压力,付出了更多的努力去调整心态,在不久之前才从误区中走出来。这段经历留待之后再说吧,可能这是每个技术人员都会碰到的人生经历,每个人都会遭遇的迷茫时期,走过来就成长了。
09年上半年,运营组经过半年的努力,成功的把所有内部系统统一到一起,制作出符合QQ邮箱特色的运营统一平台,虽然不是那么华丽,但是正如QQ邮箱一样,简洁实用,我想,简洁实用是广研的标签,我曾经和好多同事聊天的时候说过广研的系统很山寨,但是做过程序员的人都知道,再好的系统和平台,都不如自己的一亩三分田,因为我的地盘我做主。
(待续)