类库大魔王
类库大魔王 多年C++、Go项目经验,长期从事跨平台(Windows/macOS/iOS/Android)应用架构设计与开发。

Relay Bugs


Relay在线上时不时报些bug,不但客户和公司的人怨言颇多,我也苦不堪言。每次出现问题的时候,美国的PM都会在邮件里说Relay是个very important的东西,万万不能出问题,可是我怎么没看出公司对Relay有very important的重视和投入呢!整个项目除了web前端页面,其他的几乎是我一个人在开发和维护,而且我全职投入也就不到一年时间,后面就重心放在其他项目了,特性仍然在加,bug仍然要改,投入时间却是越来越少,直到现在每个月都不能保证有一二十个人时在上面。前些天一个QA说Relay的bug最多了,这时另一个开发帮忙说是因为投入时间太少。虽然说的是实话,但仍让我感到很惊讶,总算还有人知道实情。可是那些PM,Director之类的却不知是真不了解情况还是故意视而不见。

前天又一报了一次某个流出不来的问题,美国的support把web截图,日志以及netstat情况都发给我。从中可以了解到的是,流有进没出,netstat看出口有700多个CLOSE_WAIT,日志上没有任何有关出口异常的记录。昨天跟协议实现的原作者讨教了一番,再自己review了几遍代码,我觉得这次发现了一个可能性非常大的root cause,每次select只有5ms超时,如果返回0就没有任何动静退出流程了,考虑到那么多CLOSE_WAIT的情况,我觉得这个可能性很大啊。

改进的方法至少有两种,一是不用select,用epoll,但这样就失去了可移植性,二是select前加入FD_SET的socket都先判断一遍,不正常的都不加并关掉,这个方法的问题在于是否有可靠的判断socket正常的方法,getsockopt也许可以,也许不可以。还有个问题是,怎么搞出那么多CLOSE_WAIT来。

昨天还发现一些其他问题。一个root的进程重启后打不开了其他普通用户进程创建的shared memory,于是后面的逻辑就不正常了,这真是没预料到的事,难道shared memory只能用同一个用户创建的进程打开吗。进程退出的通知的漏掉的,我是用netlink实现的进程退出监控,为此还特别要求进程要root启动,可是后来发现有漏的。当初每启动一个子进程都会有个线程一直等它结束然后waitpid,后来换了netlink我没有注册子进程退出信号,就把子进程的父进程改成init了,于是好像不那么可靠了。

这些问题隐隐约约都觉得不是很难改的问题,但真要动手做又觉得有点棘手呢。

感觉本文不错,不妨小额鼓励我一下!
如果你有Visa、MasterCard之类的国际银行卡,也可以考虑以下选项:
如果你看不到评论框,说明Disqus被墙了。