我曾经在一个有内部任务跟踪系统的地方工作。大不了,你想。很多地方都是这样做的。好吧,在这家特殊的公司,有时你会陷入悲伤的深渊,你会发出一个请求,但再也没有收到它的消息……除非你竭尽全力。
让我们稍作准备。那是某年的六月,晚上九点三十分左右。我想我正在为“最后一道防线”调试团队待命,我被正在争论中断问题的经理类型通知我。似乎这个团队做了某种代码推送,现在他们在某个集群中完全崩溃了:“0 在线用户”类型的事情。
事件经理让我找出负载均衡器正在做什么来检查有问题的系统的健康状况,所以我去看了。结果他们在端口 80 上收到了一个小的 HTTP 请求,有点像这样:“GET /status HTTP/1.0”。
但是……损坏的集群中的那些没有在端口 80 上侦听。
我问他们是否做了端口接管的事情(其中一个进程可以主动将监听套接字交给将要替换它的那个),但后来注意到他们正在运行 Java,但我认为没有。这种东西只在这次演出的某些 C++ 后端进程中真正看到过。
我问他们是否以这样一种方式重新启动,即他们试图在旧进程关闭之前将端口 80 与新进程绑定。蟋蟀。
无论如何,由于缺乏相关工程师的回应,我继续前进,发现在另一个(健康的)位置戳他们的另一个实例会得到“我还活着”类型的回应。对我来说,这似乎是确凿的证据:没有对 HC 的响应 = 没有来自负载均衡器的爱 = 没有用户。
几分钟过去了,工程师没有回复,所以我只是用盒子上的魔力踢了一个 java 实例的头,看看会发生什么。几分钟后,它重新启动,现在它正在侦听端口 80 并响应健康检查。不出所料,它开始接收来自负载均衡器的请求,并且用户数量开始攀升。
我建议了一项后续任务:当他们的东西无法获得所需的所有端口时,它们应该自行终止。此外,运行任务的东西也应该设置为检查所有端口,如果不能满足,*它*应该终止任务。
现在,好吧,当然,这是 hacky。该程序应该能够在端口 80 不立即可用的情况下存活下来。它还应该有某种方式从其他进程“移交”。或者,您知道,它可以每次都绑定到一个新端口,并且只更新它在服务目录中的条目。有很多方法可以解决这个问题。但是,考虑到上下文,我选择了最容易实现的目标。当人们泡茶有困难时,你不想让他们煮沸海洋。
不管怎样,他们开始重启任务,服务慢慢恢复正常。我掉线去睡觉了。
两个月过去了。他们一直有与没有健康检查有关的中断。它们都是可以预防的。它们会在我准备回家的时候发生,所以我会错过我的公共汽车,不得不等一个小时等下一班。那种废话。
我开始计算与 HC 相关的中断。二、三、四。
在某个时候,我已经结束了,并在工程主管的桌子上放了一张便利贴,指着修复这件事的任务并恳求他们参与进来。我是通过成为这个特定的“坏警察”。现在是管理层处理它的时候了。
又一个月过去了。然后,在 9 月下旬的一天,有人突然出现在我们的 IRC 频道中,说他们已经开启了健康检查,现在必须对其进行测试,我们能帮忙吗?我碰巧在那儿,抓住了他们的一台机器,并迅速搞砸了他们的一个 Java 进程,让它挂起。 (我忘了我做了什么,但 SIGSTOP 似乎是合理的。)
任务运行器注意到并将其设置为不健康。大约三分钟后,它杀死了它,然后重新启动它。四分钟后,它仍在重新启动,也许再过四分钟,它终于再次活跃起来并接受请求。
我告诉这个人它确实有效,但大约需要十分钟才能恢复到有用状态。他们感谢我检查,那是我最后一次听说。显然他们对此没有意见。
考虑到与*网站* 相比,这种访问事物的方法让更多人使用该服务,您会认为它很重要。但是,不,他们只是顺其自然。
然后今天,我读了一篇文章,有人发现他们的系统有大约 1.2 GB 的字符串,里面全是反斜杠,因为他们使用 JSON 作为内部状态,并且它不断转义 ” 字符,所以它变成了 \\\\\\ \\\\\\\\\\\\\\\\\\\”类型的废话。那部分对我来说是新的,但其余部分的描述似乎太熟悉了。
然后我去了……嘿,我想我知道那个特别的马戏团!
结果——同样的马戏团,同样的大象,不同的狗屎。