项目特点:运行环境为RedHat Linux 9.0,分布式系统,无用户界面,,采用消息队列+状态机的运行机制,要求不间断运行的服务性程序。
本项目的特征是需求相对明确,无用户接口,系统规模中等,所以开发模型采用瀑布模型。分成需求分析,概要设计,详细设计,编码,测试几个阶段。
在项目的后期仅有1个需求变更,且影响较小,证明采取瀑布模型是合理的。
预计:4月底-8月底
实际:4月下旬-10月上旬
需求分析 |
概要设计 |
详细设计 |
编码 |
测试 |
4月下旬-5月下旬 17.6% |
5月下旬-6月中旬 11.8% |
6月上旬-7月下旬 23.5% |
7月下旬-8月中旬 17.6% |
8月中旬-10月上旬
29.4% |
预计:
实际:
需求分析 |
概要设计 |
详细设计 |
编码 |
测试 |
最多时3人 平时2人 |
最多时3人 平时2人 |
最多时3人 平时2人 |
最多时3人 平时2人 |
最多时5人 平时2人 |
预计:
实际:
子系统名称 |
简单模块 |
中等模块 |
复杂模块 |
新写代码量 |
复用代码量 |
总代码量 |
B |
4 |
3 |
6 |
8700 |
2531 |
11231 |
A |
8 |
3 |
1 |
3422 |
2376 |
5798 |
测试程序 |
12 |
1 |
1 |
2546 |
0行 |
2546 |
注:
代码量的单位为“行”,统计方法:在linux下用wc –l sourcefile 命令查看
简单模块:逻辑简单,无复杂操作,代码量在100行左右,本系统中主要为对容器的管理
中等模块:逻辑一般,代码量在300行左右,本系统中主要为消息接收、处理的模块
复杂模块:逻辑复杂,或有新写的算法,代码量在350行以上,本系统中主要为状态机
子系统名称 |
需求 |
概要设计 |
详细设计 |
编码 |
总计 |
代码质量 |
B |
0 |
3 |
3 |
8 |
14 |
1087行/个 |
A |
1 |
1 |
2 |
2 |
6 |
1711行/个 |
注:
代码质量显示的是平均几行代码中存在一个Bug,计算方式:新写代码量/编码阶段的缺陷
这里仅统计在项目开发周期中各阶段引入的缺陷,更详细的Bug信息已单独整理并提交测试部输入TD数据库。
“工欲善其事,必先利其器”,利用好工具可以大大地提高效率,在这个项目中我们也采用了很多工具,希望对以后类似项目有参考作用:
Ø 用Rose建模,用Visio画网络拓扑图、状态图。画复杂的状态图时,采用Visio比Rose更直观、简洁。
Ø 版本管理采用Visual SourceSafe6.0
Ø 编码:VC++ 6.0 + Visual Assist插件
Ø 利用Samba,并“映射网络驱动器”,这样就不用在Windows与Linux之间来回传文件了。
Ø 调试:发现程序有异常退出时,用gdb运行程序,并使它爆掉,然后在gdb中输入info stack就可以知道程序在哪里爆掉了。在程序中输出调试信息并观察之,也是一种麻烦但有效的方法。
Ø 在VC中打开源文件查看,从SourceSafe上check out一个新版本时不关闭VC中打开的文件,VC有时不会提示文件被更新,这样如果继续编辑源文件并check in,会导致文件内容丢失!为保险起见,建议check out或get latest version时,先全部关闭VC中打开的文件。
ABC项目在各阶段产生的主要文档如下:
《ABC需求说明书_B部分.doc》
《ABC需求说明书_A部分.doc》
《ABC概要设计.doc》
《ABC详细设计_B部分.doc》
《ABC详细设计_A部分.doc》
《ABC用户手册.doc》
《ABC技术白皮书.doc》
《ABC 缺陷修正记录》
内存泄漏检测:
1) 在压力下运行1-3天,查看内存占有率的变化,如果内存占用率一直递增,则可初步判断有内存泄漏
2) 重载new/delete与malloc/free,在容器中记录分配的内存的地址与长度,释放内存时删除内存分配记录,程序退出时查看容器中是否还有未删除的记录,如果有,则可能有内存泄漏。这种方法只能针对源代码进行检查,对于没有源代码的第三方库则无法检测。
3) 用内存泄漏检测工具valgrind进行检查,这种工具可以检查没有源代码的第三方库中的内存泄漏
4) OSip库中的内存分配函数为smalloc,sfree,直接用第二种方法无法检查,但可以用同样思路,修改smalloc,sfree的代码来实现内存泄漏的检测。
压力测试:
1) 专业的测试工具虽然功能强大,但不一定符合实际需要。可以根据实际需求编写模拟工具。
2) SIPp工具可以模拟SIP客户端与服务端,并可以多路并发、统计
测试:
测试人员最好能够在需求分析时就介入项目,并进行全程跟踪,这样对系统的理解就更深入,设计测试用例时就更有针对性。
设计测试用例时,多考虑异常情况的测试,毕竟测试的目的是发现bug,而不仅仅是验证。
时间分配:
项目历时5个月多,比预期(4月底-8月底结束)有延迟,原因为以下两个方面:
1) 项目进行的过程中人员变更。在详细设计时换了一次,在测试时换了一次,对进度产生了一定的影响。
2) 在测试阶段,与ABC相配合的模块如aa,bb,cc都在进行相应的变更,导致测试时问题定位,以及等待其他模块修正时都有时间上的影响。
从项目时间的实际分配比例也可反映这一点。详细设计与测试分别占23.5% 与29.4%
技术方案:
采用消息队列+状态机的运行机制,比一个Session对应一个处理线程的方案更优秀,能支持很大并发量的处理,同时采用负载均衡,使系统拥有较好的可伸缩性(Scalability)。
评审:
从本项目的缺陷分布可以看出,各阶段的评审对提高产品质量有很大的帮助。特别是本次项目中的代码审查时发现了很多错误,比在测试阶段发现bug后再去重现、定位要高效的多。如果没条件进行代码评审,也可以在开发人员之间互相检查对方的代码。
评审时,最好能够将相关资料提早发给参加评审的人员,参见评审的人员也要有所准备,避免走过场。
状态机编程:
有两种主流方式可以实现状态机的编程,一种是switch…case方式,每个状态对应一个函数,在函数的分支内对本状态的各种消息进行处理。优点是逻辑清晰,容易维护;缺点是重复代码多。另一种是面向对象的方式,每个状态对应一个对象,状态转换通过切换对象来实现,消息处理由对象的方法实现。优点是代码冗余少,缺点是不够清晰,不容易维护。
在本项目中,B采用第一种方法,A采用第二种方法,根据项目实践来看,采用第一种方法更好,毕竟状态机的逻辑都较复杂,可维护性很重要。
代码复用:
在本项目中,复用的代码量占总代码量的比例分别为:B 22.54% , A 40.98%,比例相对较高,这对提高生产率,减少Bug量有很大的帮助。经过实际项目检验的代码的是公司的宝贵财产,在今后的项目中我们要多注意项目的积累、重用,“不要重复发明轮子”。
以上项目统计数据以及总结可供今后类似项目参考,好的经验要不断地总结并借鉴,不足的地方考虑改进,这样我们团队的开发能力才会不断提高。
本项目统计数据与项目特征以及项目开发时的背景有很大的关系,有其独特性,但以后做的项目多了,数据积累多了,就可总结出其共性,从而对我们的项目估计、项目管理有很大的帮助。
本次项目的成果不仅仅是ABC产品本身,项目经验的积累以及伴随着项目成长起来的人才才是公司最大的财富。