人人网移动开发架构

作者简介

闫志东,人人网3G事业部高级技术经理,资深工程师,人人网技术委员会委员,目前负责人人网3G部门服务器架构方面的工作,他在基于C++、Java的服务器技术和架构方面拥有多年经验。个人非常喜欢阅读计算机技术、科幻、历史类书籍。

闻华强,人人网3G事业部高级技术经理,资深工程师,是人人网3G部门客户端技术负责人,他有长达七年的移动终端开发和管理经验。阳光男孩,热爱体育运动,对《明朝那些事儿》爱不释手,是忠实的明矾。

马小东,人人网3G事业部产品经理,在移动互联网业界浸淫七年,对很多产品大趋势的把握和细节设计有非常独到的看法。爱手机、爱生活、爱人人。

前言

说起手机操作平台的发展先要说移动终端的发展,因为平台的发展离不开移动终端,近十年移动终端发展和未来移动终端趋势大体可分为以下四个个阶段:

第一个阶段:功能终端。满足用户基本通信需求,如发短信、打电话,附加些贪食蛇、推箱子小游戏。

第二个阶段:智能化的终端。可扩展第三方应用,实现上网浏览等互联网基础功能,以诺基亚S60手机为代表的。

第三个阶段:互联网和平台化的终端。手机和互联网更加紧密,浏览器、流媒体更加强大,互联网应用和手机系统特性结合的 更加紧密;手机成为了一个平台,用户可以通过下载第三方应用来DIY这款终端,如偏好音乐,可以下载音乐类型的应用。代表为iPhone、Android 和Windows Phone 7。

第四个阶段(未来趋势):物联网化的智能终端。此阶段的特点是现实生活和网络通过传感设备结合的更加紧密。

目前我们处于第三个阶段,对用户而言,由于收入不同、兴趣爱好不同、需求偏好的不同以及手机私人属性和随身性的特点,产生了不同的用户体验;对各个厂商而 言,由于目标市场的定位不同、商业利益的不同、技术背景不同,造就了不同的手机操作系统。最终形成了手机操作平台多元化的局面。

目前主流手机操作平台可分为:Symbian、Android、iPhone OS 、MTK、Windows mobile、Wp7六种。下面分别简述下这六个平台的情况。

Symbian:昔日王者,虽然眼下受到了android和iPhone的强势狙击,被其瓜分了部分市场,但是价格低,易用性强,应用程序多,加上诺基亚的品牌、渠道等优势,在短期内智能机霸主地位很难撼动。中期来看市场中心下移走中低端智能机路线,长期来看,有可能被WP7取代。如果它不革自己的命,那么很可能被别人革命。

Android:势如破竹,据国外媒体报道Android在去年第四季度已超过Symbian成为全球最大智能手机平台,结束了在 Symbian在智能机领域长达10年的统治地位。作为后来者,Android借鉴了iPhone的操作体验,但是由于Android完全开源,对于手机 厂商和运营商来讲,很容易定制成自己特色和服务的手机,加上Android强大的互联网功能,因而获得二者的青睐。完全开源是把双刃剑,由于各厂商分别定 义了各自的产品,这种不标准和不统一会给第三方软件适配带来门槛,会导致在单个某型号的移动终端Android应用偏少,所以Android有可能成为智 能手机中的山寨机。

iPhone OS:神话缔造者,从热销的程度我们可以看出iPhone 4创造的奇迹。超炫的UI设计,良好的交互操作,海量的应用,牢牢占领高端市场。从短期来看,iPhone 4突出的优势会让它再火一段时间。但是由于是自有系统,市场占有量取决于苹果手机终端用户认可情况,所以长期看,主要取决于苹果手机发展和竞争对手的变 化。

Windows mobile:廉颇老矣,尚能饭否?无论从UI视觉效果,还是从易用性,还是第三方应用,Windows mobile 都完败Iphone和Android。壮士暮年,该退隐江湖了。

MTK:山寨大王, MTK是一个封闭的环境,不支持可扩展的应用,同时原功能也不完善,总之是个半成品。需要中间厂商来完善。相比较来讲,第三方程序少,易用性一般。山寨机的价格和功能形成的性价比优势,占据低端市场。

WP7:救世主,作为微软和诺基亚的救命稻草是值得期待的,笔者曾经体验过WP7,采用卷轴式UI设计风格,使UI体验别具一格。系统 和互联网应用的紧密结合,加上诺基亚和微软的强力支持。这个操作系统是值得期待的,有望在智能机领域形成WP7、Android、iPhone三足鼎立的 局面。

上述六大平台分别对应不同的体验和功能实现。对产品设计人员和开发人员而言,它们通常会参照移动终端的UI设计规范。因为移动终端系统本身定义了一些常用 的控件和响应方式。产品保持与终端系统的一致,不但可以降低开发成本,而且易于用户学习和使用。面对诸多平台,尤其是各个平台功能特点不尽相同,操作方式 不同,屏幕大小不同,而每个主流平台又有相当规模的用户群,拥有众多不同的UI规范,这对于全平台的产品而言,无疑是具有灾难性的。

本文就人人网移动开发中不同终端平台的差异和架构统一问题,以及相关服务器架构进行探讨。

移动终端之江山一统历史历历在目

人人网(原名:校内网),从08年下半年开始手机软件的研发,当时国内一二线的互联网公司也已经开始了移动互联网的布局,但已发布并可供参考的产品并不多,尤其是 SNS本身也还是一个新的互联业务,让我们的用户可以在手机上方便地访问SNS,这可一下把我们难住了。为了可以快速推出第一个版本试水,我们先是选择 JavaME平台来开发第一个人人的手机客户端。

人人网的主要业务包括新鲜事,个人主页(状态,日志,相册,留言),好友,站内信,聊天,游戏等等,这些业务都互相关联与衬托,并围绕好友关系 (Social Graph),如果要把这些业务都搬到手机,短时间内根本无法完成,因为客户端类的软件与浏览器的网页在展现与交互上有非常大的差异,手机的屏幕大小限制 也给设计带来了很大的困难,无疑是雪上加霜。当时我们挑选了用户常用的几个业务,新鲜事,个人主页(状态,日志,相册,留言),好友,站内信,按主站顶部 导航的排版方式,设计了一多标签的导航界面,每个标签一个业务,页面跳转同主站,如下图:

人人网移动开发架构

图1

看上去这个设计非常简约明到几乎完美,代码也非常好实现,大家激情澎湃,斗志昂扬准备迎接移动互联网的又一个奇迹,也许你和我以及我们的产品经理一样, 低估了这一切,人人网的业务可不像聊天软件那样单纯,当我们的工程师各自完成自己的分配到的业务,并开始处理不同业务之间界面的跳转时,不详的预感笼罩了 整个团队,当时的轻率导致了严重危机,大家知道,在我们通过浏览器访问网页,页面中超链接可以让你随意跳转到任何一个页面,且这些页面并不一定是同一个业 务的相关页面,如我从个人主页也可以直接跳转到好友(跨标签),而且通过浏览器的后退按钮可以返回前面的页面,客户端类软件可不能做成这样的自由,我们应 该怎么处理不同业务界面的跳转呢?当时大家理解的跳转,根本没有考虑到不同业务之间后退的问题,而且浏览器的页面跳转,浏览器本身是不用知道下个界面是哪 个业务,而客户端必须知道,否则根本无法处理事件交互。技术慌了,产品经理也慌了,眼看承诺的交付时间一天天临近,大家还是没有想出一个非常好的办法,多 次尝试失败,有的方案,页面的跳转连我们自己都晕过去了,最后我们的第一个版本的JavaME 客户端1.0以失败告终。

首战不利,大家心里都不是滋味,虽然通过后几个月的努力,最后我们决定将1.2版本的客户端以beta 版本的形式发布,并公开提供了下载,除了拍照上传这个功能让我们值得高兴一下之外,其它功能也许只是让我们感觉能用而已。JavaME的失利让我们从自负 中清醒,骄兵必败。经过一段时间的讨论与分析,大家一致认为,我们需要一个手机浏览器,人人的业务不论在PC端还是手机端,最理想的展现方式还是浏览器, 于是我们开始手机浏览器研发道路,我们花了3-4个月的时间,开发出了我们第一个基于JavaME的浏览器引擎,代号:Across(为什么起这个名,后 面说)。浏览器引擎架构参考Webkit,如下图:

人人网移动开发架构

图2 Across浏览器结构图

上图中蓝色部分是我们引擎的实现部分,红色的JS,CSS及Plug-in是未来的计划,从技术角度看来,这个架构看上去非常的美,模块功能划分清晰且 扩展性强,我们只要重写Render Engine可以把一个普通的页面渲染成我们想要的任何效果,遗憾的是最终我们还是没有把浏览器这个解决方案应用到正式发布的人人客户端版本,原因很简 单,它还不是很完善。我们预先做了大量的测试用例,在完成开发以后,我们按测试用例逐条进行了测试,最终结论虽然在性能和xhtml标签支持上达到了我们 的预期,但稳定性和包体积却并没有达到理想的状态:运行时内存消耗在xhtml页面大小的8-10倍左右,如一个30K的xhtml页面完成解析,渲染必 须保证有300K左右的空闲内存,如果渲染多个页面或频繁渲染新的页面,就很容易出现崩溃(后来我们发现代码中还有存在一些内存泄漏的地方);另外,打包 以后200k的体积对于JavaME手机来说已经大了。09年上半年,Android发布了1.5的SDK,iPhone入华的消息也是传得到处都是,显 然,在这样的行业形势下,公司管理层已经对我们在JavaME上做浏览器引擎的计划失去兴趣,我们的工程师被重新安排了新的任务,Across没有见到用 户就成了历史,浏览器没有救得了我们。

痛苦中反思

09年上半年是我们最痛苦的一段时间,折腾了大半个年头,结果我们没有发布一个值得骄傲的产品,市场却快速变化着,iPhone,Android带着闪 耀的光芒进入了大家的视野,我们也不得不做出调整,开始分兵投入iPhone及Android的阵营。我们开始反省前面的失败,我们似乎走了两个极端,第 一次在考虑产品及技术的架构时过于的简单草率,以致后期面临强大的心理压力,第二次却是一个典型的过度设计案例,虽然从技术角度看这是一个非常有挑战且非 常有意思的项目,当时我们的设想是先完成JavaME平台的浏览器,然后移植Symbian等其它平台,统一架构。但是移动互联网市场近几年的急速变化, 不论从人力和时间上都不允许我们再把浏览器项目继续下去。

为什么我们要统一架构?

人人网的业务种类非常多,而且PC端都基于浏览器网页的模式,不论内容还是排版都经常需要优化变更,如果我们通过纯客户端的形式把全部现有业务迁移到到手 机端,那么,当我们完成第5个业务的迁移时,可以前两个业务主站已经发生了变更,或者客户端刚刚上线之前的某个业务已经需要兼容运行了,在这种情况下,要 么我们能快速迭代客户端版本,赶上主站的业务的迭代速度,要么我们使用浏览器或类似浏览器的模式,所有业务放在服务器做,这就是我们为什么考虑开发 Across,名字意在横跨所有手机终端平台。

真的可以统一架构吗?

可以,浏览器本身就是一个非常优秀的跨平台解决方案,但这个方案的前期投入非常大,且项目执行风险过高,人人网的业务大都是基本动态网页实现,使用了大量的AJAX及Flash技术,最终我们放弃了浏览器方案,我们要的统一架构肯定不是这个。

山穷水尽,柳暗花明

放弃了浏览器的方案,我们可谓山穷水尽,难道还有第三个方案?Facebook的iPhone应用给了我们很大灵感,看图:

人人网移动开发架构

图3

从产品的角度看,这个图显示的布局与我们第一次尝试的设计没什么区别,深入一点我们会发现,这个设计与之前的设计最大区别在于页面跳转,每个标签都有独 立的一个视图栈,理论上无限大,通过当前栈顶视图可以打开新的视图后自动压栈保存,当前视图如果要后退默认退回视图栈里保存的上一个视图的内容。那如果是 标签1的页面需要跳转到标签2对应的页面怎么办呢,是否自动切标签?答案是不切,标签只是用于业务导航,且有独立的视图栈,视图栈中的页面可以与业务无 关,打个很好理解的比方:当我们在使用Chrome的浏览器时,我们同时在多个标签分别打开多个不同网站或页面,也可以打开同样的网站或页面,每个标签都 有一个独立的后退的记录,这种设计非常有规律,用户容易理解不容易晕,现在页面跳转及后退的问题很好的解决了。不论JavaME,还是iPhone或者 Android的客户端,我们都使用了同样的设计。

数风流人物,还看今朝

当我们客户端都使用了这种标签+视图栈的方案以后,我们的各平台在设计上基本达到了统一,并在现有设计上快速迭代演进。大家可能想了,在代码层统一这才 叫本事,也许你没错,但是我们不会轻意再做这样高风险的尝试,如今手机平台的差异相当的大,就从主流平台的开发语言看就够你折腾了,JavaME及 Android是使用的Java , iPhone使用的是 Objective-C,Symbian是纯C++, 现在诺基亚与微软联姻WP7,可WP7将不再支持C/C++的开发,主推C# + Silverlight,好吧,我们只能再观察一下了。

在接下来的一到两年,移动互联网将以前所未有的速度发展,大部分互联网公司都开始了或已经推出了较成熟的移动终端的解决方案,创业公司也会层出不穷,推出各种优秀的移动终端应用:移动支付,LBS,基本通讯簿的即时通信,手机音乐,手机视频,手机阅读等等,iPad点燃平板电脑的硝烟,平板的设计再次给了我们很大的挑战,数风流人物,还看今朝。

高可靠性和可扩展的服务

现在移动互联网拼的都是服务,客户端良好的用户体验背后,都有强大的服务器技术支撑,人人网也不外如是。

业务层次模型

人人网采用JavaEE技术作为主要的业务解决方案,基本按照通用的JavaEE模型进行架构设计,如下图: 

人人网移动开发架构

图4 人人网业务层次模型

  • WEB层基于REST风格和MVC设计模式,为用户提供基于WEB的访问接口人人网采用的是自己开发的WEB框架 Rose,该框架基于Spring Framework,类似RoR框架,增强了对Controller编码部分的默认约定和REST风格URL的支持,该项目前已开源,下载地址为http://code.google.com/p/paoding-rose/
  • 业 务层封装业务逻辑,为WEB层提供业务接口,操作数据访问层提供的数据。人人网开发了自己的SOA框架XOA以支持业务层抽象,该框架结合Rose框架, 以REST风格对业务进行分类、消息格式封装和路由,如以下URL:xoa://blog.xoa.renren.com/photo/{user- id}/{photo-id}该URL代表某用户的某个照片,操作 GET/PUT/POST/DELETE分别对应对应照片资源的读、修改、新增、删除。即通过资源+操作的方式对外提供Service。 XOA支持远程调用,并可以通过简单添加服务器的方式进行横向扩展。该框架目前准备开源,敬请关注。
  • 数据访问层提供对数据库访问的封装人人网使用Java语言开发了自己的Object-Relation Mapping框架JADE(Java Database Engine),并支持数据库的水平横向切分。该框架和Rose框架一体开源,下载地址相同。
  • 数 据持久层数据的持久存储,主要采用MySQL数据库,并且开发了自己的海量存储系统Nuclear。Rose、Jade、XOA作为集成度很高的一整套解 决方案,在人人网大量采用,大大降低了开发成本,并在框架级解决了服务于企业解决方案的JavaEE技术在互联网领域的适用性。

可扩展的高性能系统

人人网每天都要承受亿级PV海量用户的并发压力,和其它大型互联网站点类似,服务器架构方面做了很多工作。

高性能数据存储系统

在数据存储方面,人人网做了以下工作:

  • 和其它互联网大型站点相同,MySQL数据库做水平拆分以支持横向扩展
  • 人人网作为国内第一大SNS网站,欲存海量UGC数据,必有海量存储系统。Nuclear存储系统在高性能、高可靠、可扩展的海量数据存储需求下横空出世。

Nuclear本身的数据存储基于Key-Value形式,底层可以使用MySQL/Memory, Cassandra, TC, Redis等存储引擎,提供弱结构化的查询功能。

  • 高扩展性一个Nuclear集群支持1到n(n<264)个节点(Node)的规模
  • 高可靠性单个节点的crash永远对系统的运行造成影响,不存在单点风险。系统永远可写入。
  • 高性能在4个节点、一般服务器配置情况下有测试数据表明单节点访问可达15862 req/s, 平均单次请求耗时仅5ms。

可扩展的高性能业务服务系统

人人网的业务层是支持分布式、可横向扩展的。

  • 人人网主要使用JavaEE架构进行业务开发,其中Spring提供的IoC和AOP功能分别起到了业务对象装配和横向关注点分离的良好 抽象。XOA框架基于Spring和netty,使用google的spdy协议作为网络传输协议,除享受到Spring红利之外,也提供了基于Java NIO的网络高性能服务器环境。单个XOA服务是无状态的,具有幂等性,XOA客户端使用Java NIO、通过Keep alive保持对各个后台服务器的TCP长连接,可实时监测后台服务器的健康状况,并把用户请求负载分散到各个后台服务器上,在单个节点失效的情况下不影 响服务,如图5所示:

    人人网移动开发架构

    图5 XOA负载均衡
  • 很多关键性的业务对性能要求特别高,也需要借助很多Linux操作系统的特性,这时Java的优化已经不能满足需求,需要使用 C++语言进行开发。人人网采用ICE框架, 进行这部分业务的开发,它解决了Java、C++等多种语言开发的框架和通讯问题。人人网目前使用ICE进行开发的业务层称之为中间层,主要解决类似搜 索、用户好友关系计算等性能要求苛刻的底层关键性业务问题。其运维模式和XOA类似。和其它大型网站一样,业务层使用Memcached作为业务层的分布 式数据缓存,且根据业务将缓存集群划分为多个池,集中进行管理,如图6所示: 

    人人网移动开发架构

  • 图6 Memcached Pool

  • 在WEB层,使用目前性能最高的Servlet容器产品Resin作为HTTP Server,使用自行开发的Java WEB MVC框架Rose对用户请求请求分发。负载均衡方面使用了F5或者nginx。为了减少Session复制同步的开销,每台WEB Server都禁用Servlet Session, 即每台服务器都是无状态的,单个Web Server失效后,不会发生用户状态丢失的问题。用户状态的跟踪由中间层统一处理。

对移动终端的支持

服务器对移动终端的支持主要是通过HTTP协议提供json数据接口实现的,服务器基本采用了人人网共同的架构:

  • HTTP WEB层做了更多的MVC抽象,除了提供基于html的Page View之外,还生成只提供json或者其他数据格式的Feed View。
  • 服务器通过gzip压缩减少流量,节省用户资费。
  • 客户端构建REST风格的HTTP请求,WEB服务器下发数据完成远程调用。

3G的API层直接面向移动终端,提供基于HTTP和其他Socket协议的服务器访问接口,并在业务层抽象出3G部门自己的公共平台,如图4所示: 

人人网移动开发架构

图7 3G API架构

除此之外,针对移动终端的特点和中国特色的移动互联网环境,做了一些特殊的工作:

  • 低端机型运算能力和内存资源都有限,API平台做了相应优化
    • 复杂的运算服务器完成,减少移动终端负载。如图片的缩放、裁剪运算、图片质量就是服务器进行的。
    • 客户端和服务器进行的数据输入输出尽量减小,这样可以节省内存存储。在表示相同数据的情况下,尽量采用数据量小且易于解析的格式。API平台使用了JSON,没有使用XML
  • 为了减少用户资费,传输流量进行了控制
    • nginx开启gzip压缩,减少网络传输流量。
    • 中国移动的cmwap网关会自动对服务器输出的gzip流进行解压缩,从而使nginx的zip压缩失去了意义。这种情况下,api服务器对输出进行gzip压缩后,作为普通二进制流进行响应输出。
    • 除了纯文本的json之外,api服务器也支持基于google protocol buffers格式的输出,从而提供更紧凑的格式输出。
  • 提高客户端访问速度
    • Api平台支持基于逻辑时序的批处理操作,将多个api的网络接口调用合并为一个,减少多次tcp握手造成的巨大时间损耗,提高客户端每个UI界面的响应和显示速度。