• "千里之堤毁于蚁穴"重点项目不能交付之谜(一)泥淖中的验收测试


      公司有个系统A,最近忙着验收测试,但测了个把月,由于性能和稳定性不够理想,客户不同意验收。

      前些天从我们Team去支援该项目的一个兄弟和我谈到这个系统很难整,我恰好也对这个神秘系统比较感兴趣。于是大致浏览一下,不得不佩服该系统的UI;
    1. 清爽,漂亮,看起来非常大气
    2. 全程Ajax,几乎不刷新界面
    3. 最神奇的是功能似乎比客户端软件还强,可以拖拽数据到树,可以右键处理一些事务,可编辑表格那些"基本功能"当然都有

       [第一个问题浮出水面]
       我迫不及待的想知道该系统的瑕疵。在兄弟输入的指定产品Id后,问题暴露了,获取该产品的MBOM(Manufacturing BOM)详细清单的时候非常慢,一问原因,原来该产品的所有子孙节点一共有200多个,因为BOM是成树状分布的,比如说散热器是由小风扇*1,散热片*1,小螺钉*2,主板卡*2四个子物料组成的,如果散热片也是自产的话,那么就多了铝制散热鳍片*1,铜芯*1两个孙节点,..... ;

       [第一个问题的分析]

       一看随着数量增多,速度成比例变慢,我心中忽然有了想法,应该是和数据库交互过多.开启http请求监控工具,果然是这个原因,我一点击查看详情,浏览器就不停的请求服务器.于是我猜想,目前的处理方式是通过BLL.BOM查找物料信息并添加到界面,界面添加后顺便检查是否有次级物料,如果有子物料的话,继续查找子节点(Lazy Initialization).次数一多,自然就慢了.因此我们只要减少浏览器到服务器,和服务器到数据库的交互次数即可大幅提高速度.

      [试图解决问题一]

     从问题看我以为只要为BLL.BOM添加Early initialization方法,其DAL实现是一个递归查询语句 .ORACLE 语句如下

    SELECT level, m.*FROM materiel m
    START 
    WITH materiel_id=:materielId
    CONNECT 
    BY prior materiel_id=materiel_p_id

       随后在我本机的技术可行性测试(为测试某一技术是否可行模拟需求进行的小测试)中,效果非常理想,复杂产品(200子孙)时间和原先只有10条以下子孙料号的简单产品耗时相当。从解决方案上来看,似乎非常简单,应该改问题能立马见效.乐呵呵的将解决思路,sql语句发过去,自我陶醉自己是不是太厉害了;难住一个Team的难题唰一下就让我给解决了.

       那兄弟看到我的Mail很高兴,说虽然他只负责另外一个模块,但这个Bug困扰很久了云云,有空帮他看看我.乐呵呵的想,"困扰"不过如此.  

     [问题一变复杂了]

       我还顺便从vss上拷一份代码到本地,来测试下自己的成果 ,一看代码,我糊了,此程序没有BLL,没有DAL,就只有界面,所有的后台代码都在'*.aspx.cs'下面,前台引用的js文件有5,6个之外,前台还有上千行的js函数.调试半天,总算把流程弄清楚了,

    从流程上分析,该流程主要做两件事

    1.从数据库查询资料

    2.将物料插入到一个tree里面

    经仔细研究,还是可以做Early initialization的,只不过这次初始化的对象为一个Dom元素tree而已.但对这一方案最终如何执行,能否执行我心中已经没底了.

    随后,我参加了一次该team关于此问题的一次技术讨论,

    讨论的结果如下

    1,代码尽量不能变动太大

    2,尝试采用 Early initialization方式解决该问题,(解决的思路大致是通过将递归查找出来的数据集在后台生成html代码添加到界面上去(改动量相对较大),或将数据集格式化成Js插件能载入的格式,一次性在前台载入)

    3,在1不能满足的前提下,砍掉一次性展开所有子孙节点的功能.(尽管此功能在客户需求文档中已经明确提出) 


    [问题2,问题3,问题N都出现了]

    随着对该项目的继续了解,一些问题又陆陆续续的冒了出来

    如:

    1)该软件非常吃客户端内存,没错,就是客户端,256/甚至512内存的机子跑这程式很吃力。

    2)在将界面修改值保存到数据库时,经常失败;

    3)在只有几个用户测试的情况下,服务器已经跑不动了

    【该项目的简单介绍】

       该项目是我们的重点项目之一,它是一个以BOM为核心的一个工程系统.涉及工程设计、工艺制造设计、生产制造,采购,销售.设计用户500人,公司,客户都很看重该系统.在资源分配上也优先处理

      它关系公司产品线的未来UI走向,如果效果很好,将会运用到其它产品上去.

      目前该项目延期快一年了,目前任处于漫长的验收测试过程中.项目组压力很大,但目前还无法给出交付的具体时间,项目组成员对该项目已经开始厌烦.客户也开始不感冒...

      

    【关于该项目的感触:】

    在这个案例中,一个表面光鲜的软件,内部可以说是相当丑陋,最终导致项目的失败.(注:本文赞同项目延期或预算超出为项目失败的观点) 。

     从案例中我们可以看到,该软件在尚未交付的情况下,已经"腐烂",成了"全新的遗留代码"[1] 。

    产生这种状况的原因也许有许多,比如使用了其它公司的Js代码,团队中途换人了,客户需求老变。但这些原因在所有中几乎都是无可避免的.

    -----------------------------------------------------------------------------------------------------------

    本文在前几天发过,但内容已大幅修改,故重发一次.另外,由于问题的逐渐深入,这个话题可能会写成一个系列.

    只是可能,因为发贴真的很累,我又真的很懒.

    有网友提到,我提出的解决方案很简单,确实简单,而且根本不能说已经解决该问题.其实本文的主要观点也并不在于如何解决问题,而是试图找出为何会出现这些问题,如何避免这些看似小问题的大问题

    注:
    [1]遗留代码:无法理解的,难以修改的代码.《修改代码的艺术》,Machael C. Feathers


  • 相关阅读:
    laravel MethodNotAllowedHttpException错误一个原因
    laravel查看执行sql的
    二维,多维数组排序array_multisort()函数的使用
    REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR获取客户端IP
    学习正则笔记
    关于apidoc文档生成不了的一个原因
    laravel 表单验证 Exists 规则的基本使用方法
    laravel 500错误的一个解决办法
    关于laravel 用paginate()取值取不到的问题
    C语言寒假大作战02
  • 原文地址:https://www.cnblogs.com/shinn/p/1338001.html
Copyright © 2020-2023  润新知