代码改变世界

开发中学习——维测方法的重要性

2013-02-03 11:45  Peter87  阅读(1611)  评论(0编辑  收藏  举报

首次体会到维测方法的重要性

之前写代码,关注的都是软件的基本功能,从来没有注意到编写代码时加上一些与实现功能不相关的维测逻辑的重要性。参加工作半年来,在编写代码的 同时考虑代码的后期维护是我学到的有用的第一课。这一课很重要,也悄然的让我对操作系统中的日志模块有了兴趣,当然,这是后话了。

这次深刻的体会主要来自于一次问题的定位过程。这个问题,三个人花了两天的时间去定位。而如果事先在代码中留下线索,就不用这样费时费劲的反复编译、验证和分析。问题的背景与定位过程在下面叙述。

背景

系统当中存在三个模块:FMDCFEFMfunction module,关注具体业务,通过对FE转发的不同消息对应用层呈现不同的业务通知;DCdata collector,进行关键数据的采集,并将采集到的数据统一发送到FE,由FE转发到 给各个FMFEforward engine,将DC发送过来的数据分送到FM。对于为什么DC不能直接将数据发送到FM而要在FE转一圈是因为FM有多个,这里因为呈现方便故意简化之。

如上图,DC上报的数据要能够转发给FM有一前提,也就是对应的FM必须事先在FE注册其所关注的数据类型。

问题

DC上报的数据FM没有收到,而初步定位结论为FE上没有FM对应的注册信息,所以所有到达FE的数据一个也没有发送到FM。并且,这个问题出现场景比较特别,问题在重新启动整个系统的时候会复现,而在重启FM对应进程的时候没有问题。所以争论点就出来了。

争论点

FM的注册流程在复位FM所属进程和复位整个系统是统一的,所以FM认定问题肯定是在出在FE的注册处理上。而FE对于远到而来的注册请求是一概全收并且不会主动去更改和删除,如今没有FM对应的注册数据,问题便是没有收到过FM的注册请求,也就是说根因还是在FM上:到底有没有发送过注册请求。

问题梳理清楚了,解决方法本来很简单,就是确认下FM在初始化的时候有没有向FE注册成功,或者FEFM初始化的过程当中有没有接收到FM的注册请求便可以解决这个问题。然而纠结的地方就在于双方都没有对应的日志记录,当初的考虑是注册流程很简单根本不会出现这个差错,但现在双方陷入了僵局。

定位过程:

幸运的是,我在自己的环境上试验了一下,发现当前的环境也有这个问题。所以,我首先想到的,便是给FE的关键路径加入调试日志,先确定问题是否出在FE。 接下来花了一天的时间编译版本、验证和提取日志。

之后,FMFE一起验证、核对日志,最终发现FE的确没有收到FM的注册消息。在细读FM注册部分的代码之后发现FM使用的事件机制有偏差,造成了当前版本的时序问题。具体原因为FM在发送注册信息之前需要先获取到FE的地址,但是时序问题使得FM在获取到正确的FE地址之前便发送注册信息,使得注册失败。巧的是该时序问题在复位A对应的应用进程时不会发生,有点点复杂,不详述。

 

上面这些是整个问题的来龙去脉,现在回想起来很简单,但是在当时是觉得很恼人的一件事情。双方争执来争执去,周末也调动人一起看问题。不过历经了这一次定位,让自己深刻的体会到维护的重要性也是一件不错的经历。起码让自己意识到了两点:

1)编写代码时不能仅仅去考虑其功能实现,在维护上也需要多一些考虑。不然,问题出现时就有重复的事情做了。其实,问题能够复现还好,要是不能复现可就更麻烦点。

2)无形之中对操作系统的日志模块对了很多好感。突然发现,日志模块对于后期的维护是多么的重要。