实施项目复盘 – ****商城1期 项目概况 2010年10月中标; 2010年10月项目组投入; 2011年6月系统上线;平均每日订单量几十张; 2011年11月,由于KPI的驱动,市场投入,每日订单量达到1100张,系统整体崩溃;通过剥离大压力业务(将该模块重写)1周内实现恢复上线运营; 2012年3月,系统全面改写完成,系统每日订单量10000+张;系统平稳运行;再未出现问题。 复盘重点 项目质量问题 从2011年8月份开始,就开始有一些奇怪的现象,某一些访问用户会发现网站短暂不能访问,刷新一下就可以恢复访问了(问题是出在数据库连接耗尽);从2011年10月份开始,客户方由于KPI的压力,开始在市场发力,短期内就将订单上升到1100张左右;事实上从日300张订单开始,以前曾经看见的问题就开始比较频繁的复现;到日订单1100张左右的时候,在短时间内就能将所有服务器全部拖死,只有通过重启Web服务、数据库服务来修复;2011年12月份,客户要求系统下线(因为商城系统和其他的系统共享了一部分服务器,商城的崩溃也会拖垮其他的服务),采取的措施是: 1. 进行系统级优化,有3倍左右性能提升,但是效果还是不明显; 2. 经过2周,将访问压力最大的业务,从框架里拉出来重写,彻底解决这次危机; 3. 经过2个月,用4个工程师,将商城代码全面重写,彻底解决这一问题; 复盘的重点在于: 1、 为什么每日订单量1100左右,就会使得2台数据库服务器 + 4台App服务器群在10分钟内的全部垮掉? 2、 我们事前是否知道,会有这类问题的发生,当时为什么没有采取解决方案? 3、 解决方案既然如此简单、廉价地达到,为什么在过去的1年中,我们已经付出了几十倍的成本,都从来没有人去做? 团队合作问题 这个项目有一个特殊性是:当时我们的一个合作伙伴,与我们签署了战略合作协议;大致的意见是说:合作伙伴可以以我们公司的战略合作伙伴的名义出现在客户面前,在售前阶段,可以得到我们的销售、市场、客户经理、解决方案支持;如果是合作伙伴打下来的单子,实施交给合作伙伴,我们拿走我们所需的利润。 平心而论,商城项目的打单过程中,合作伙伴是有巨大贡献的。所以项目后期实施主体由合作伙伴提供,是一个必然的结果。所以,我们按照fixed price(固定价格)的方式将合同的实施包给了合作伙伴。 在实施过程中,实施团队分为2个部分,一部分包括项目经理(我们公司)、测试团队(我们公司出了测试主管,测试工程师由合作伙伴出)、SA(我们公司出)在客户的现场(河北);另一方面,开发经理(合作伙伴)、开发团队(合作伙伴)在合作伙伴处(广州),不到2个月的时间,两个团队就开始出现巨大的冲突,客户方的项目指责后端的开发经理、开发团队不了解前端压力,专业程度差;后端的开发团队职责前方的项目经理以及测试团队无所事事,对项目无所帮助。 在项目后期,现场问题的排查过程显得困难重重(远程团队无法通过VPN登录目标服务器,于是所有问题的排查都只能不断交互,而且现场的支持团队严重缺乏对于系统的了解),需求了解过程也是顾虑重重(在不清楚实现难度的情况下的贸然时间、工作量承诺,无疑是给自己挖坑)。 复盘的重点在于: 1. 按照合同来看,这样的组织结构是否存在问题? 2. 从实施角度来看,这样的组织结构是否存在问题? 3. 为什么现场的团队在一年的时间中都没有培养起来? 4. 如果是成本问题,那么这个项目成本是否在最初来看就是存在巨大风险的? 5. 更为恰当的选择是什么? 复盘过程 项目质量问题 为什么每日订单量1100左右,就会使得2台数据库服务器 + 4台App服务器群在10分钟内的全部垮掉? 现场问题现象是: 1. 数据库连接池耗尽,数据库连接池无法快速释放;数据库迅速拖死; 2. Application server的连接数急剧上升,无法释放,导致APP server假死; 3. 整个应用安装在2台DB、4台APP Server上(1台DB用来做冷备,实际只有1台可以运作;4台APP和其他应用复用,但是其他的应用基本上是静态页面,服务器能力也还算富裕。) 4. 在用户侧,用户会看见系统的提示:数据库无法连接,请用户稍后再试,然后整个网站全部挂掉。 当时的访问量情况是: 1. 在每日订单量上800以后,就会比较频繁地发生类似问题;订单量上1100的时候,极端情况下,重启后15分钟以后,系统就会崩溃; 2. 按照标准算法,构成800张订单,可能会需要每日80万的访问量支撑,而在这个具体案例中,访问量撑死也只有每天30-40万左右; 那么很奇怪的就是:按照这样的访问量,即使我不做任何cache、不做任何优化,用一台服务器来抗这些压力,也还是可行的,那么这个系统脆弱到我难以理解的层面呢? 系统的架构是:Drupal + PHP走前端展示、后端走Java + Oracle架构,前后两个数据库之间,从设计原理上来说应该是单向同步,但是实际上其中逻辑关系异常复杂。 这个性能问题的出现,可以简单的归结为几个原因: 1、 使用了不恰当的架构:这个项目有一个特点是,客户需求不明晰,这一点是可以理解的,对于运营商来说:不是核心系统,没有KPI去驱动,说白了,就没有人真正想过到底要这个系统干什么。既然用户的需求极其简单、那么我们就应该采用最简单的架构实现了就好了,没有必要采用一个复杂的架构来应对根本没有发生的需求; 2、 团队对于这套架构的掌握非常粗浅:事实上,在我看来,当时的开发团队中没有一个人有足够的能力说能够驾驭这套架构,即使是架构提出人也是如此; 3、 Drupal架构本身应对大访问量(即使我们的访问量并不大)的能力本身就不好,需要一些周边的配合,这些技巧、技能对于一支没有这方面经验的团队来说,就得靠项目来积累经验了; 所以,这个问题的根源是错误地使用了复杂架构,并且这样的复杂架构并没有降低团队工作量,得不偿失;团队能力与所使用的架构不匹配,又没有强有力的反对声音提出,导致错误不断扩张开去;SA不介入到具体开发中去了解,具体的指导,导致架构理想性成分比较重。 要解决这类问题,我的一个经验是:如果确实存在某一些技术风险,那么让SA带领一个团队做预研,预研的结果为一个demo;在后期,SA需要介入项目的开发,他可以不写代码,但是必须为团队在架构使用方面提出自己的意见,并且有义务帮助团队蹚过这些技术难关。 理由很简单,从个人利益角度出发,如果我不用对后续的实施负责,那么我完全可以为了显示自己的专业性,而将架构做的极其专业、灵活;而这些所谓的专业、灵活如果并不能解决项目核心问题,那么这些设计将变成项目的额外负担。仅仅依赖于个人的专业性,让我觉得不那么放心,还是让SA走得更深入一些的好。 我们事前是否知道,会有这类问题的发生,当时为什么没有采取解决方案? 这个问题,实际上已经在实施之前就可以简单地预见。因为合作伙伴在另外一个省的商城项目中使用的是同样的架构,在上线后,几乎没有什么并发量,仅仅跑了一个10个并发的批量订单处理,就将系统直接拖死了。而且,这个问题在2年后的今天也没有得到解决。 而在这个项目,将会大量复用之前项目的代码,这意味着,从基因上,我们就会将这些问题继承下来。而这些情况,PM是很清楚的。 那么为什么当时不正视这个问题呢?从事后看来,这是一个复合因素: 一方面,由于我们和合作公司之间建立的是固定金额合同,也就是说,当项目出现问题,需要额外资源投入的时候,合作公司有义务投入所需要的所有资源,而我们不必为此买一分钱的单;但是事实证明,当时所签署的SOW上存在巨大的问题,一般这样的单方固定金额合同,都是将用户的要求,一股脑扔给合同伙伴去抗,也就是背对背的要求、背对背的付款条件。而在这个项目中,实际上给合作伙伴的SOW中不是这样做的,留下了很多漏洞,导致后期压力完全压在我们身上。而且,这个问题导致的另外一个不好的结果是:给项目实施人员,特别是PM带来了一种虚拟的安全感,同时,也错误的认为:既然都是合作伙伴抗,那么他们做技术决定就可以了;但是,除非你干脆和客户说清楚,或者干脆从项目最前端撤下来,让合作伙伴抗上去,只要你顶在前面,压力最后就是你来承担的;同时,即使有SA对PM进行技术的支持,但是,做为PM也必须对项目负责,也就是说,SA如何能够说服你:同样的架构,在A地出现的问题至今没有排除,而同样的代码在我的项目中就不会出问题?而且,这样的严重技术风险,不是嘴巴说说就可以的,是需要得到实际测试验证的。 当时,也有同事提供了这个问题,要求得到回答,PM的答复是:这个项目就是运营商做着看看的,不会有多少访问量的。事后看来,这个问题想得过于简单了,过于耍小聪明了;你如何知道客户就不会推广? 当项目在性能测试的时候,包括测试主管、PM恐怕都没有仔细看性能测试报告,事实上,我事后来看这份性能测试报告的时候,发现这个性能问题,实际上在进行性能测试的时候就已经暴露出来了。当时可能因为着急拿初验,就没有进行进一步排查。 在上线运营过程中,由于开发团队在异地,而本地的维护团队仅仅能维护系统、数据库的内容,对于应用几乎手足无措;而每日极少的订单量也给了PM一个虚假的安全感,从而使得这些问题没有进一步排查下去。 这样风险被这样或者那样的问题包裹着,主动被动地不加动作,最后突然爆发,使得大家都焦头烂额。 最终解决方案既然如此简单、廉价地达到,为什么在过去的1年中,我们已经付出了几十倍的成本,都从来没有人去做? 最终,用了3-4个人,3-4个月时间,就完成了整个系统从老架构中迁移出来,平稳运行。 也就是说,我们只是投入了16个人月就能完成这些项目。当然,由于现场的人维护了1年,对用户的需求比较了解一些,也会加速项目的研发;但是无论如何,和之前项目整体研发投入将近30个人相比,这个成本实在是微不足道的。 那么为什么我们即使作为一种风险方案,也没有去尝试那样做一下呢? 更多的还是一种虚拟的安全感,既然系统今天没有出现问题,那就不要去动他好了。 另外一个说法是无奈: 1、 现场没有人 – 确实,现场后期没有太多人员在,但是好歹也保持了3个现场工程师的配置,而且说实话,恐怕确实没啥事情可做; 2、 架构已经定死了,没有人懂,没有办法修改:即使不能全面修改,从当中摘出几个流程恐怕还是能够做得到的,因为后来的整改方案就是这样开始起步的;其次,既然合作公司的新来工程师可以在2个月内接手项目的修改,为什么我们的工程师不能去合作公司现场一起学习呢? 3、 事实上,我的理解是:从如此低廉的修改成本,比对出现如此巨大的问题;以及之前我们所消耗的那么长时间,花了如此多的费用;这一对比很难从客观上找到太多理由。 也许过于苛刻,但是,我理解的问题根源是:一种虚幻的安全感麻痹了太多人,风险意识严重不足,得过且过现象严重;记得我曾经和一个同事在咖啡厅聊起这个项目的时候,打开了网站的首页,试用了一会;结果是:1分钟毙掉了UE、5分钟毙掉了流程。结论是:在大公司做事,少了很多主动精神,当做自己事情做得人。 这也是我们现在提倡Acc ount PM的概念,而不仅仅是PM。Acc ount PM如何能够为公司带来新的单子?提供超出客户期望的内容,挖掘用户深层期望;而不仅仅是你让我做什么,我就做什么。这样被动的做事心态,恐怕很难做好APM的。 团队合作问题 按照合同来看,这样的组织结构是否存在问题? 从合同角度出发,这样的组织结构是不完整的,既然一个单子里面的大部分实施成本已经交给了合作公司,那么我们就不应该再投入多少人了(当然,SOW签署出问题,是一个巨大的原因)。即使在项目前期,合作公司没有和我们质疑SOW的时候,我们就已经投入了1个PM、1个SA、1个测试主管、2个工程师;按照我们标准成本计算,这样的投入,实际上根本不能由项目的成本去cover。而既然是合作公司fixed price的方式来做,我们只需要投入一个PM就够了。而且需要有意识地将合作伙伴在职责上钉死。 而我们完全让合作伙伴躲在我们背后,这样客户方面的风险、压力就完全由我们承担了,如果是那样的话,我们预留的费用是不足以完成这个项目的。 从实施角度来看,这样的组织结构是否存在问题? 即使抛开合同问题,从实施角度来说,这样的组织资源配备也是存在问题的。首先,在项目前期,将SA、测试团队、PM、需求人员全程放在客户方,实在是没有太大必要的。 因为在客户方,存在着出差费用,而这笔费用往往很高,所以,如果实施团队在现场,一定会有不得已的理由,比如需求人员必须跟踪用户需求等等。而且这个项目进展过程中,在上线之前实际上用户需求很少,这就让人很质疑,为什么采用这样的组织结构安排方式了。从客观上很难说得通。 比如,2012年末,我们通过一个运维合同,之所以在客户现场放了10多个人,原因是,由于第三方供应商为我们提供的都是本地人员,价格方面本身就比从北京派出的要低,同时我们也不需要承担出差费用;其次,运维人员经常需要上线,以及和客户面对面沟通,因为在运维过程中,客户的需求往往是零散而大量的,比如仅仅过了4个月,由于人手不足,未完成的积压需求已经达到了70多项,由此可见需要沟通的频度。 将测试团队和开发团队分离,使得沟通成本上升,甚至我们在此过程中,还付出了出差成本。而令我觉得匪夷所思的,即使为了和客户保持持续的沟通,但是开发团队在广州、为什么不在客户现场以及广州之间穿梭办公?这种情况严重到,在整个项目过程(1年多)中,PM都没有回过一次广州(即使他的location是广州),也没有面对面地和开发团队开过一次会。这一点一度让想破头,都想不明白。也许是连续1个月以上的出差可以申请出差津贴,每个月有12500元?但是,即使你是长期出差中,回到location的地点,这笔费用也是可以一样拿的啊,我实在不是特别明白。因为1年多时间都没有过去面对面沟通一次,这绝对是有很充足的理由的。 为什么现场的团队在一年的时间中都没有培养起来? 现场团队即使到了项目开始1年以后,也还是无法更改一行代码,也不清楚修改什么地方,就可以达到某一个效果。 这一点一度让我觉得不可思议。因为合作伙伴的一个新工程师可以在2个月内接手项目的修改,我们的人员为什么花了1年时间都不能学会呢?按说我们的工程师质量至少从薪资、过往经历方面,要比合作伙伴的工程师高端一些。 在这一方面,我的理解是2个原因在起作用: 1. 虚拟的安全感:没事的时候,没有一个人愿意去学一下,既然大家的base都不在客户现场,意味着无论无客户现场、还是去广州,成本都是一样的,那么为什么不能派现场人员到开发现场一起合作开发1-2个月呢? 2. 压力传导不足:现场除了项目经理,其他人感受到的压力不足。我在河北的几个月很明显的感觉到这一点,各种客观的理由,强调自己的职责;但是如果仅仅为了调试一个服务器,我似乎没有必要要一个专门的人摆在现场啊,而且正式系统的服务器、系统服务,我们都没有权限访问,那么为什么需要这样的一个岗位呢?对SA的定义应该不是网络管理员。但是这个同事用这样的理由告诉我,让我觉得很是惊讶。 无论如何,现场和开发团队的脱节,使得整个问题排错过程、修改过程变得困难重重。 如果是成本问题,那么这个项目成本是否在最初来看就是存在巨大风险的? 是的。这个项目的成本风险异常巨大,因为按照项目的金额,我们几乎不可能全部由自己的人员完成实施。而且类似的系统不是开发完成就可以把团队全部撤掉的,必然还会需要现场留人去应付用户的需求,以及排错 – 以为合同上总会有6个月的终验的,终验没有结束,作为应用软件系统,总是免不了去做一些事情的。 而这个风险最终完全爆发出来,最后我核了一下成本的缺口,几乎是原先成本的100%以上。即使在组织结构上存在一些不足,但是成本上的风险是客观存在的。最后,合作伙伴看见SOW中存在一些问题,就此将压力完全转嫁回来,就导致后面的事情很难收拾了。 更为恰当的选择是什么? 如果结合这个项目的实际情况来看,我认为比较恰当的团队模式是: 项目开发阶段: 1. PM、需求放在现场,其他人员不出差;两地穿梭办公; 2. 在项目开发阶段,无论是从现有团队剥离、还是找到未来的维护人员,这部分人员都需要保留下来,且事先就能掌握系统的一些内容,达到可修改外围程序、修改流程为目的,1-2个人员就足够了; 项目维护阶段: 1. PM和维护人员放在现场不动;平时没事的时候,维护人员盯住,PM可以机动到其他短时间项目中去; 2. 开发团队支持前端维护人员的工作,应需调度; 启示 1、 对于这一类根据用户实现需求类的项目,如果缺乏一个经过技术磨合、缺乏稳定的团队;千万不要使用复杂架构,这将为后来的实施,留下巨大隐患; 2、 无论别人帮你做什么,最后责任都是你要抗的;所以,当PM看见一些风险的时候,你敢于说出来,即使面临冲突也要说,要不然,最后的问题只能你自己来抗; 3、 维持现状的做法,有其合理性;但是,在结果已经预先判知的情况下,大胆一些,往往是破局的关键。可想而知,如果在订单量每天只有10多张的时候,我们更换系统,风险会远远小于每天1000多张订单的时候。缺乏这样的动作勇气,无非是温水煮青蛙;大风险的突然爆发,仅仅是量变积累下的质变,而不是真的有那么不可预期。
|