豌豆荚范怀宇:我们在豌豆荚2.0重构时遇到的坑

来源:互联网 发布:阿里云数据库连接2003 编辑:程序博客网 时间:2024/05/21 14:57

豌豆荚范怀宇:我们在豌豆荚2.0重构时遇到的坑

产品豌豆荚MDCC
摘要:2012年10月19-20日,中国移动开发者大会2012在北京国家会议中心举办,豌豆荚 2.0 重构项目技术负责人范怀宇在“平台与技术”分论坛上做了题为《豌豆荚2.0重构经验谈》的主题演讲,演讲中,范怀宇向与会者分享了开发豌豆荚2.0的思路和解决方案。

重构还是重写,这是个问题

在明确了问题之后,接下来的选择是:重构,还是重写?

所谓重构就是沿用1.0的架构方向,继续选择.Net平台,把我们认为耦合严重的代码重新整理,使它的结构更加清晰,能够支持未来的需求开发,这样的重构模式好处是开发成本低,但它的弊端是无法解决我们在.Net平台上碰到的性能之类的顽疾。

另外一条路就是重新写,我们从零开始,再做一个豌豆荚,我们使用全新的架构降低耦合,改用C++这样的Native语言,来够解决豌豆荚1.0中的启动速度慢等性能的问题。但可以想象,重写的成本非常高,在豌豆荚1.0版本的代码积累完全不能复用。并且,在2.0版本重写的同时,1.0版本还需要不断维护,出新功能,这对于当时一个30人团队而言风险还是很大。

但是综合考虑了这两种策略的优缺,我们相信,在未来的一两年甚至更长时间,我们还是会不断地做很多新功能,做更多的产品尝试,需要不断提升性能等基础体验,因此,我们需要的是一个更稳定更高效的架构,于是,我们选择了重写。

走适合自己的路

选择重写,我们评估过不同的解决方案。比如说,使用传统的Windows架构,所谓传统Windows架构就是类似于MVC的架构模型,界面用WTL来搭,在Controller中把业务逻辑塞上去。这样的架构在过去十几年的Windows开发中普遍被采用,相对来说,开发效率会比较低,面对我们想要的新的产品的效果以及需求来说,做起来会很麻烦。比如说我们想加入一些动画效果,一些很酷的切换效果,都会需要很长时间来开发。于是就想了另外一种比较流行的解决方案,就是DirectUI,在这样的解决方案里面,我们会用XML的配置文件来描述界面,使用C++等高效本地语言来实现逻辑,用Lua、Python这样的脚本来做粘合。这样的解决方案能够在保持高性能的同时,提供更漂亮的界面效果。

基于DirectUI各公司有不同的实现,也有一些放出来给大家用的解决方案,比如说迅雷的Bolt,但是这些方案在我们看来都有一个弊端,就是比较封闭,没有一个在整个业界足够有影响力的通用解决方案。一个相对封闭的解决方案意味着,无论我们招什么样的人,都会面临着不小的学习成本,因为需要他了解这个平台,然后再了解豌豆荚的开发。对于一个小公司来讲,这样的学习成本确实十分高。

用“Web的思想”做PC客户端

此外,我们还可以继续沿用1.0的思想,还是基于Web的方式来开发客户端应用。所谓基于Web的方式,就是在整个应用内部,绝大部分的UI设计和通信模式都和Web应用类似,用HTML以及CSS、JS来绘制界面,通过Ajax等调用来获取数据。

为了提高整个Web体验,我们选择内嵌一个Webkit内核,来保证前端开发的简易性。同时,鉴于1.0的经验,我们觉得一个灵活规范的通信模式,在这样的架构中是非常重要的。使用这样的架构,保证了开放性,在开发人员上也可以有更多的选择,并且可以很好的满足我们对产品的需求。基于这些考虑,我们最终选择的方案是继续使用基于Web的技术来开发Windows应用。

但是这个解决方案我们并没有任何可以参考的成功案例,对于豌豆荚来说有很多技术问题都是未知的。为了能够把这样的重构做得顺利,我们先制定了很完整的产品需求文档,它取自于一年多来的经验。我们把其中一些证明好的功能做了重新的设计,把一些用户觉得不好的功能给拿掉了,并且通过我们的判断,增加了一些提升基础体验的新功能。比如说多设备管理,设备数据离线缓存等等。在产品设计基础上,我们花了比较长的时间,重新做了架构设计,其中特别针对1.0中碰到的一些技术障碍,给出了更优的解决方案。

还有一个重要的点就是我们做了很多的demo来尝试,尝试整个架构方案,看看我们觉得有瓶颈的地方是否能解决,通过这些demo,使我们坚信我们可以沿着这个技术方向来做应用,把2.0版本搭建起来。

全新的豌豆荚2.0的架构其实看上去和Web应用比较相似。前端页面主要基于Webkit内核,用Html、CSS、JS的技术绘制界面,满足标准的Web规范,甚至可以跑在Chrome上来测试。其他需要和Windows的一些原生效果比较相似的界面部分,我们从Chromium中抽取了一套UI框架来构建。在后端的逻辑主要分成两个部分,一个是平台层,提供基础的功能服务,比如说与手机通信,和服务端通信,和操作系统通信等等。

图:豌豆荚2.0技术架构图

除此之外,我们把业务逻辑封装成不同的服务,每一个服务最重要一点是独立,彼此之间完全没有耦合。服务和服务之间,后台和前端之间,全部通过通信层来进行交互。在通信层上流转的数据,我们称之为communication数据,这些数据都是用ProtocalBuffer来描述。

通信层是整个架构比较核心的部分。它的协议定义是来自于一个开源的项目——Onering,这个项目的初衷也是受了豌豆荚1.0的启发,觉得1.0采取的基于Web开发客户端应用的架构很符合未来的发展,在这个基础上,他们做了一些协议的定义,把整个通信方式模拟得更像一个Http请求,把通信端分成三个部分,一个是前端,一个是后端服务,另一个是操作系统,定义了这三个端,六个方向的通信实现的策略。我们主要参考了其中的协议定义,在实现方面,Onering项目原来实现会比较简单和粗放。在豌豆荚的实现中,我们使用了定义的Webkit和C++语言作为前后端的实现基础,用Protocal Buffer来描述通信协议的数据。

图:OneRingAjax

在前端开发中两个最主要的通信方式,一个是主动调用,它的使用方式非常像Ajax调用。举个例子,如果前端想请求123这台设备上的联系人数据,并且以json这样的格式来获取,那么他就可以发起这样一个url描述的请求,请求到AppManager这一层会做一个统一的调度,AppManager是通信层的主要实现模块,里面有应用中所有服务的信息,它会根据url找到对应的服务,用线程安全的异步调用将请求发至对应服务进行处理,所以流程与普通的Ajax请求无异。

不但前后端调用如此,服务和服务之间的通信也会完全采用同样的模式进行通信。比如说联系人服务想获取短信信息,它不能直接访问短信模块的接口,而是通过同样的方式发起一个异步请求,来获取短信的数据,以此来保证服务之间的低耦合,便于业务逻辑的扩展。

除了主动调用的模式,还有一种被动回调的模式。比如说如果联系人模块中数据更新了,从手机上获取的新的联系人数据,怎么通知前端进行刷新?我们采取的方式叫做事件/订阅的模式,前端订阅这么一个事件,当后端触发该事件的时候,也通过一种异步的回调来通知订阅者,并保证该调用是线程安全的。通过这两种通信方式,基本上满足了前后端和服务之间的所有通信,在豌豆荚2.0的实现中,被大量使用。

整个架构上中还有一个很重要的就是服务。我们希望服务之间是没有耦合的,所以在实现时我们只为每个服务定义了非常简单的API,它只有一个接口接收请求,一个接口释放数据。所有的服务都不会被其他服务来直接调用。在实现上,服务可以封装成DLL,用任意语言来实现。在豌豆荚2.0的实现中,我们考虑到了整个应用的体积问题,我们选择使用了C++的静态库方式来实现。在服务内部的设计,我们会让它更贴近我们的产品需求,我们按照设备来划分线程逻辑的,使得设备之间是完全独立的。比如你同时使用两台设备,每台设备上的缓存数据,与手机的通信,都彼此都是独立互不影响,这样可以保证同时使用两个手机的时候,都可以有很流畅的交互。

在豌豆荚2.0当中,其实我们使用了大量的开源软件。我记得在第一次提交代码时,我提交了180万行代码,其中包含了很多开源软件的实现。其中,最核心的一部分是从Chrome开源项目中抽取的基础架构部分。Chrome已经成为了业界标杆,不仅是所有的浏览器,很多现在Windows的程序也会同样采取Chrome的架构以及Chrome的一部分的代码实现。Chrome给豌豆荚带来的最重要的东西是编程模型,每个线程都有消息循环,跨线程的操作都是异步调用。因此,在实现业务时不需要关注数据访问时的并发性问题。还一个很重要的部分,Chrome对操作系统的原生API进行封装,提供了更为建议可靠的API,使得开发时可以尽量少地和操作系统API打交道。此外,它还对很多常用算法进行了封装,比如Md5,比如Sha,等等。Chrome也可以对STL做了很好的加强,对更丰富数据结构和API支持。

其实有一个基于Chrome的开源的项目叫Chromium Embeded Framework。这个项目抽取了Chromium中核心的部分,整个架构和豌豆荚2.0采用的颇为相似,现在也是被很多公司采用来开发软件。整个豌豆荚2.0的架构总结一下,其实很重要的一点就是,我们使用了一个比较新的技术的尝试。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 海贼无双3路飞二档怎么开 从海贼开始的次元通讯录 混在海贼的日子 海贼之无限吞噬 海贼之无上主宰 海贼之地府我做主 大白师兄 海贼之通臂猿果实 海贼之疯狂变异 老兵不死 南禺 混在海贼世界的日子 海贼之剑道无双 大菠萝 海贼之冰皇 麻烦哥 海贼之赏金剑神 凋零与绯红 海贼之完美进化系统 用户名 海贼之不死之神 戒烟戒酒 海贼之幻影 落叶纷飞花满天 海贼之伊姆大人 十隐 肆虐综漫从海贼开始 海贼之天赋系统 夜南听风 海贼之不服就干 后候鸟 海贼之三宫六院七十二妃 二哥 海贼之神级提取系统第八区 海贼世界的剑豪大将免费 海贼之母巢秩序txt 大海贼系统 尚青天 海贼之恶魔果实 胸前有杀气 海贼之瞳术果实 海贼之掠夺一切第八区 网游海贼之神级登录 海贼之血旗纵横 逐天之痕 海贼之我要杀bigmom 海贼杀ol 海贼之厌之歌 海贼之果实猎人 笑酒歌 不思议迷宫海贼之港 海贼之港用啥组合打好 海贼之港平民哪个出战怎么打 不思议迷宫海贼之港速刷阵容 不思议迷宫海贼之港全dp攻略 不可思议迷宫海贼之港攻略 海贼时代 海贼无双3中文版手机版下载