missalucard的专栏

最近读陈年先生的文章"凑热闹的公司都会烟消云散",读了十几遍,意犹未尽,感慨颇深。

我来小米三年了,三年前我会滔滔不绝的跟别人讲,如何带领几十个人,建立一套多么完善的质量保证体系,如何用制度让所有人都遵守软件开发的流程和秩序,等等云云;还要告诉大家,某某大公司都是这样干的,某某外企比这个干的还大,借以佐证我的思想是何等的正确和伟大。

现在想想,那时的我,SB!

2014年,我很平静的度过了,做了一年多的推送服务,写年终总结的时候,恰逢读到陈年先生的那篇文章,于是我想我一年做了这么多事情,有哪件事情可以拿出来炫耀,就像那件白衬衣呢?

于是我把所有做过的事情都列出来,然后一个一个划掉,这个事情做得太糙,这个事情做的太乱,这个,嗯,很一般;当你划掉几十件事情的时候,你的心就凉了,拔凉拔凉的;陈年先生在半层楼里放了所有的产品,却没有一个可以拿出手给雷总看的时候,,也许就是这种感觉吧。

想了几天之后,我终于想到一件小事情,也许这件事情太平凡了,以至于成为了不过大脑的生活习惯;直到昨天跟某两个互联网大公司的服务器工程师吹牛的时候,我才发现,当我把这个牛吹完的时候,他们看我的眼神中似乎有了一丝异样的光芒。

我们花了一年多的时间只做了一套服务的监控,大的改版超过了10次,N多次的代码重构,推倒重写,各种尝试,各种跳坑,解决各种瓶颈,看各种密密麻麻的log,分析各种情况,处理各种异常,等等云云

其实监控原理很简单,在测试机上跑一组case,调一下线上服务的api,判断一下服务返回的结果对不对,对了就pass,错了就报警,就这么简单,没什么难的。但是我们前前后后做了一年多。。。直到今天,改动还在继续。

1.最初的方案是这样的,E2E的测试,用一个手机接到测试机器上,然后用脚本定时驱动安卓程序,向手机里安装一个推送客户端sdk demo,然后跑android的case,给客户端发消息,看客户端是否能收到,如果收到就从手机里读出来判断正确与否。这个代码很快就写好了,测试通过,嗯不错,开始跑吧。跑了一个晚上就傻眼了,由于手机通过wifi连接网络,各种网络不稳定所导致的误报,直接让报警不断,失去了报警的意义。怎么办?换一套环境

2.既然wifi环境不好,那就直接在网络接口接一个路由器,这个路由器只提供这一台手机的网络连接,这个总该稳定了吧。跑了两个晚上,嗯,误报是少点,但是总误报数量占的比例还是很大,报警搞得大家都很紧张,怎么办?再换一套方案。

3.使用android虚拟机,这个东西直接跑到测试机器上,完全不需要wifi,这总可以了吧?实践了几天,哭了,一个是虚拟机内存占用之恐怖,连续跑几天你试一试,另外性能也有问题,读取服务器的返回值是很慢的,需要长时间的sleep,最后就是不稳定,各种不稳定。

4.取交集,手机跑case网络是瓶颈,模拟器跑case稳定是瓶颈,能不能两个一起跑,如果同一条case都fail,才报警,只有一个fail,不报警。这个方案不错吧,取了一个交集;真到写代码的时候就完蛋了,两个监控一个跑的快,一个跑的慢,你还得写一个控制程序去定期分析两边的log,乱的一塌糊涂。

抛弃android吧,我们监控的是服务,干嘛要带上客户端,尽管E2E的监控更让人感觉靠谱吧,但是这不是最根本的东西

5.直接连服务器,客户端的原理是通过push demo调用push client sdk,client sdk最终是需要调用smack包来完成xmpp消息传输的;服务端工程师做E2E测试的时候,会通过一个中间层直接调用smack连接服务器;ok有方案了,把服务端工程师用到的中间层改改,然后套用客户端smack,再模拟客户端发出的请求,最上层接上test case,就应该能工作了;不久,这个移花接木的东西开始跑了,效果还不错,明显误报少了很多,很好,把前面那些不靠谱的监控全都干掉,把这货换上,然后张灯结彩,准备喝庆功酒,但是跑了几周,问题来了,长连接不像短连接,不成功就retry,长连接一旦断了,重新bind是有问题的,并且如何检测连接是否断掉呢?

6.最初的怀疑是smack不稳定,因为看到了smack的call stack,问题应该出在smack上,smack是第三方类库,用于xmpp的连接,但是我们使用的xmpp不是标准的xmpp协议,是经过我们改造过的xmpp,smack于是也被改造过了;查了一下maven库,上面有好几个smack的版本,换个别的用用,问问消息组的同事,各种尝试之后的结论是,这不是版本问题,别的版本不支持push服务,怎么办?改造smack吧

7.先找到smack的源代码,然后各种看,各种debug,然后整理了一下smack的行为规律:a.如果网络断了,smack发消息前,自己会检测到网络断了,然后发一个<present>强制断开网络连接;b.如果客户端等待收服务的消息,那就会超时,smack感知不到网络断开了。中间层是没法对重新bind做处理的;那就只能改smack,在收发消息的时候,先检查网络情况,如果断了就重新bind,代码改完了,找android的大牛军哥去看,没出5分钟就被拍回来了,这种改动会影响到连接的状态,这个太底层,最好别动。。。这次尝试又失败了,默默的在中间层加了一些重新bind的处理逻辑,效果也不是很好

8.重新回到原点,重新一个一个log去分析,慢慢的会发现,网络不稳定是一回事;中间层的不稳定,开始慢慢的浮出水面,中间层有大约20多个package,代码里有各种继承各种重写,很多静态的变量你如果不debug,根本都不知道哪里改变的,有时候改变一点点东西,上层的case就跑不起来。怎么办?凉拌,重写吧,按照自己的需求。这个花掉了几周时间,在某一个后半夜,所有case都可以在重写的中间层上跑起来了,那一刻根本没有什么兴奋,只想回家睡觉。重写后的只有2个package,大约7-8个文件,是的,上层的case其实用到的就这点。试着跑了几周,这个世界清净了,监控明显稳定多了,但是新的瓶颈又出现了。

9.中间层稳定了,就发现上层的case写的好挫,各种不靠谱,重写吧。。。又是几周,靠谱点了。

10.又遇到问题了,一次我们看监控很正常,但是某一个开发者说他们的app收不到push了。这次事故调查的结论是服务端对这个app的配置有问题。这次事故导致的是我们不再用单一的测试账号跑case,改用各个app的账号跑case,建立新的appinfo的列表,然后一个app一个app的跑。

11.又遇到问题了,当时我们有100左右的xmq,我们遇到了这样一个问题,由于当时的升级技术问题,导致了某次升级之后,有两个xmq的服务有问题,但是监控是随机落到各个xmq上,当时在很长的时间里并没有报警;这是一次事故,怎么让以后不出现这个问题呢?我们做了paritition监控,让每次的case都只落到一个xmq上,轮询所有的xmq;上线,跑了几个月,确实也发现了一些问题。

选择逃避,选择被动的去面对生活

missalucard的专栏

相关文章:

你感兴趣的文章:

标签云: