周日晚上9点,服务器比我还想下班:论值班制度的"玄学"
周日晚上9点,服务器比我还想下班:论值班制度的”玄学”
说出来你们可能不信,今天是周日晚上9点02分,我正准备收拾东西下班,突然钉钉弹出一条消息:”某VM的系统负载有点高,建议关注一下。”
我当时的内心是崩溃的。
你说这服务器吧,平时工作日的时候什么问题都没有,Prometheus绿得发光,Grafana一片祥和,钉钉安静得像没人用过一样。可一到周末,尤其是周日晚上,它就开始给你整活了。这是什么玄学定律?服务器版的”周一恐惧症”吗?
周日的规律,只有运维才懂
作为一个在上海打工的运维工程师,我已经在这行摸爬滚打好几年了。这几年里,我总结出了一个几乎百发百中的规律:
工作日的服务器像乖巧的学生,你说什么它干什么,出了错也会提前告警。周末的服务器像青春期的孩子,你不盯着它就给你搞事情,而且专挑你放松警惕的时候搞。
周一到周五,系统稳得像上了锁。Prometheus永远绿色,告警群安静得像空了,SSH连上去看什么都正常。那种感觉,怎么说呢,就像你养了一只猫,平时都乖乖的,你知道它不会搞事情。
周六开始,各种微妙的变化就悄悄发生了。数据慢慢积累,缓存命中率开始微微下降,某些定时任务的中间结果堆积在磁盘的某个角落里。表面上一切正常,但内行人知道,这是暴风雨前的宁静。
周日上午,平静得让人不安。大部分用户都在休息,系统负载甚至比工作日还低。你看着监控面板,心想今天应该可以安安稳稳度过了。
然后周日晚上9点,钉钉响了。
这不是巧合,这是规律。
后来我仔细研究过为什么周日晚上特别容易出问题,发现原因其实很清晰:
第一,定时任务在周末积累了势能。 很多批处理任务、数据同步任务、日志归档任务都安排在周末执行。这些任务平时分散在每一天,影响不大。但周末一积累,周一早上就成了”清算”时刻。
第二,监控系统本身也有盲区。 周末的告警阈值通常会被调低,因为正常负载本身就比工作日低。但这反而会导致一个问题:真实的问题被误判为”正常波动”。
第三,人的因素。 周日晚上是心理防线最薄弱的时候。大部分人已经开始放松,准备迎接新的一周。这时候突然来一条告警,心理落差是最大的。
所以周日晚上9点的告警,影响的不只是系统,还有打工人的心态。
值班制度:听起来很美,实际很残酷
说到周日晚上的焦虑,就不得不提运维的值班制度。
很多公司都有值班制度:工作日正常班,周末轮流值班。HR在介绍的时候会说得很美好:”值班是为了保障系统稳定运行,公司会提供调休和值班补贴。”听起来很合理,对吧?
但现实是这样的:
值班的时候: 出了任何问题都是你的责任,不管几点,不管是不是你导致的。系统挂了,怪你没看好;系统没挂,但你没在第一时间响应,也怪你;系统本来好好的,值班同事不小心改了个配置搞挂了,更怪你。值班费?200块一天。你没看错,不是2000,是200。
不值班的时候: 出了问题还是要找你。因为你是这个系统的专家,别人处理不了。值班同事发消息过来,你还得远程协助,一边说”我在休假呢”,一边SSH连上去帮忙排查。
所以值班制度的本质是什么?是你本来只需要对工作日负责,现在变成了7×24小时负责。而且周末值班的200块,还不够你买咖啡提神的。
你说气人不气人?
但你说能怎么办呢?系统不会因为你周末休息就停止运行,数据不会因为你需要休息就不积累,问题不会因为你下班了就自己消失。服务器可不会心疼你,它只管跑自己的。
打工人嘛,还能咋地?干呗。
晚上9点的紧急排查
回到今天晚上9点那条告警消息。
当时我已经准备下班了,咖啡已经倒好,包已经收拾好,脑子里已经开始想回家看什么剧了。结果那条消息一弹出来,我的身体自动做出了反应:放下包,打开电脑,SSH连上去。
整个过程不超过30秒,快得连我自己都惊讶。
这就是运维的肌肉记忆。
先看看整体状态:
1 | |
3.45的负载?平时这台机器的负载只有0.5左右。这不正常。
再看内存:
1 | |
内存使用率78%,Swap用了60%。系统正在经历内存压力。
然后看进程:
1 | |
好家伙,发现了几个问题:
问题一:某个定时任务在周末堆积了大量数据。 原来这个任务设计是每天处理10万条数据,但周末没人消费,数据堆积了50万条。周日晚上任务一启动,数据库查询直接把CPU打满了。
问题二:日志文件没有做轮转。 /var/log目录下有一个日志文件已经超过了2GB,还在继续写入。难怪磁盘空间告警。
问题三:某个容器配置有问题。 Docker容器分配了4GB内存,但应用实际只需要2GB。剩下的2GB被浪费了,导致其他容器内存不足。
三个问题叠加在一起,导致负载从0.5飙到了3.45。这在平时可能不算什么,但周日晚上没有足够的系统管理员在线,这个问题如果不处理,明天早上一定会爆发。
处理ing:和时间赛跑
既然发现了问题,那就开始处理呗。
说实话,这种周日晚上加班修bug的情况,我已经习惯了。但今天特别累,因为这是连续第三周周末临时被叫来处理问题了。
前两周分别是:
- 上上周六:某台数据库的连接池满了,原因是周末访问量比预期多了三倍
- 上周日:某个API服务突然开始疯狂报错,原因是某个配置在周末过期了
都是那种”明明上周还好好的,怎么突然就出问题了”的情况。排查半天,最后发现是某个配置在某个周期性的时间点会触发一个隐藏的bug。不出问题根本发现不了,一出问题就是连环爆炸。
运维工作最难的部分就在这里:你永远不知道哪个角落藏着一个定时炸弹,而它的引爆时间,往往是你最不想被打扰的时候。
可能是半夜两点,可能是节假日中午,也可能是周日晚上九点。
今天就是周日晚上九点。
我一边处理问题,一边在心里默默记下:周一要开个会,讨论一下”周末值班制度优化方案”。这个议题听起来很正式,但其实核心就一句话:能不能让服务器也过周末,别在周日晚上搞事情?
显然,这是不可能的。服务器又听不懂人话。
修复完成:代价是什么
花了大概一个半小时,终于把三个问题都处理了:
停掉了那个还在跑的批量处理任务,改成了分批执行,设置每批只处理5万条,给系统留点喘息空间。
清理了旧的日志文件,配置了日志轮转(logrotate),限制单个日志文件最大500MB,超过就自动压缩归档。
调整了Docker容器内存配置,从4GB降到了2GB,释放出来的资源给其他服务用。
系统负载从3.45降回了0.8,一切恢复正常。
但是,这个”修复”是有代价的。
我原本计划晚上9点半下班,搞完已经11点了。本来约了朋友周日晚上吃饭,结果放了人家鸽子,人家吃完饭发消息问我”你不是说8点就能走吗”,我只能苦笑”临时加班”。本来想在周日晚上好好休息,结果比工作日还累。
你说这值不值?
从系统稳定性角度来说,值。毕竟防止了明天可能发生的大规模故障。明天周一早上9点可是高峰期,如果系统在那时候崩溃,影响的用户数是周末的几十倍。
从个人生活角度来说,不值。用一个完整的周日晚上,换来了系统的”正常运行”。这笔账怎么算都不划算,毕竟200块的值班费还不够这一顿被放鸽子的饭钱。
但你说运维这份工作,不就是这样吗?你的价值,恰恰体现在那些”没有发生的事情”里。系统没挂,你没有功劳;系统挂了,你有过失;系统差点挂但你及时处理了,你只有苦劳。这种”无功就是过”的职业属性,真的挺让人哭笑不得的。
感悟:打工人的自我修养
今天的故事让我有几条感悟,想分享给同样在做运维的同行们:
第一,不要相信”周末不会有事”的幻觉。
越是觉得”应该没问题”的时候,越容易出问题。周末的系统表面上风平浪静,实际上各种定时任务、批处理、缓存过期都在暗处等着你。Prometheus绿不代表真的没问题,可能是监控没覆盖到那个角落。保持警惕是运维的基本素养,哪怕在周日晚上,也要留一只眼睛盯着监控。
第二,值班制度的坑,只有经历过的人才懂。
值班的时候,你要对整个系统的稳定运行负责,24小时待命;不值班的时候,你还是脱不了干系,因为别人搞不定。这种”7×24小时负责制”是运维工作的隐藏成本,在谈薪资的时候很少被考虑进去。HR说”我们值班有调休”,但调休是用来干什么的?是用来弥补你周六周日的加班的,而不是用来让你真正休息的。
第三,学会和焦虑共存。
运维这个工作,最难的不是技术问题,而是心态问题。你要学会接受”随时可能被叫走”的不确定性,要学会在休息日和加班之间找到平衡,要学会在”系统没挂但你很累”的时候给自己找点乐子。我现在的做法是:加班完了之后,一定要去吃一顿好的,不是外卖,是堂食。哪怕是楼下便利店的关东煮,也比不吃强。
第四,记录是最好的防御。
今天这个问题,其实之前就有苗头。如果我之前有记录”每周日晚上负载会上升”这个规律,可能就会提前做一些预防性措施。比如在周六晚上手动执行一次日志清理,或者在周日早上检查一下批处理任务的队列长度。下次遇到类似情况,就知道该提前检查什么了,而不是等问题爆发了再救火。
写给周一早上的自己
好了,今天的故事讲完了。
最后我想对周一早上可能遇到类似问题的运维同行说几句:
如果明天早上你也遇到了类似的问题,先深呼吸,然后告诉自己:
“这很正常,这就是运维工作的日常。”
然后打开电脑,开始排查。不要慌,不要急,也不要抱怨。问题总是能解决的,只是需要时间和耐心。
实在不行,就想想那句话:**”服务器不会心疼你,但你的身体是你自己的。”** 该吃饭吃饭,该睡觉睡觉。系统是公司的,但命是你自己的。
好了,今天的博客就写到这里。
明天又是新的一天。服务器会继续跑,问题会继续出现,而我也会继续在这里,和你们一起,做那个默默守护系统稳定的人。
晚安。
作者:小六,一个在上海努力生存的普通打工人,今天的周日以加班结束,但明天太阳照常升起