关于我如何用一个bug让自己加班到凌晨三点这件事

发布时间:2026/8/30 23:12:25

关于我如何用一个bug让自己加班到凌晨三点这件事
这事儿得从昨天下午说起。周五下午四点半我已经在收拾东西准备跑路了。测试那边丢过来一个issue说生产环境有个接口偶尔超时让我看一眼。偶尔超时这种词儿在程序员字典里基本等于大概率是你的问题但我懒得查日志。我打开skywalking看了下调用链没毛病啊响应时间平均120ms挺正常的。又翻了翻nginx日志也没有明显慢请求。我就回了一句这边看正常再观察一下。然后测试就炸了。他贴了张截图请求时间15:47:23响应时间3.2秒。我一看这个时间点心里咯噔一下——那个时间我刚发完一个版本重启了服务。你以为的bug其实是feature接下来就是一个小时的血泪排查。先怀疑是缓存失效导致回源DB查了redis命中率99.8%正常。再怀疑是日志打印太多把IO堵了看了下logback的异步队列积压为0正常。怀疑是GC问题看了眼GC日志频率正常单次耗时也都在50ms以内。然后我注意到一个细节这个超时请求里带了一个特殊的headerx-request-id的格式是abc-123-def这种但正常我们内部生成的格式是UUID.randomUUID().toString()全是横杠分段的那种。我就顺着这个header往上查发现这个请求经过了一个网关服务而网关里有个拦截器会对这个header做一次MD5计算然后塞到MDC里用于链路追踪。MD5计算本身不慢但这个拦截器的实现是这样的String requestId request.getHeader(x-request-id); if (StringUtils.isNotBlank(requestId)) { // 为了兼容旧版本对非标准格式的requestId做一次摘要 if (!requestId.matches(^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$)) { requestId DigestUtils.md5DigestAsHex(requestId.getBytes()); } }这个正则每次请求进来都要执行一次。大部分请求的requestId都是标准UUID匹配很快。但那个特殊请求的requestId是不带横杠的短格式正则引擎在做回溯匹配的时候复杂度直接起飞了。再加上那个时间点服务刚重启JIT还没热身解释执行模式下这个正则匹配的耗时从纳秒级飙升到了秒级。问题找到了改法很简单把正则匹配改成尝试按UUID格式解析抛异常就说明不是标准格式再做MD5。try { UUID.fromString(requestId); } catch (IllegalArgumentException e) { requestId DigestUtils.md5DigestAsHex(requestId.getBytes()); }三行代码改完测试环境验证通过预发布验证通过准备发生产。有时候顺风顺水反而让人害怕发生产的流程走了半个多小时——code review、merge、构建镜像、滚动更新。整个过程异常顺利顺到我心里有点发毛。果然上线后五分钟监控突然弹出一堆告警错误率飙到15%全是NullPointerException。我当时整个人是懵的。改的就是一个拦截器里的小逻辑怎么干出NPE了赶紧回滚。回滚后服务恢复然后我开始看错误日志。堆栈指向的代码行是String traceId MDC.get(traceId); Span span tracer.buildSpan(traceId).start();traceId是null所以buildSpan的时候抛了NPE。那traceId为什么是null呢因为设置traceId的逻辑就在我改的那个拦截器里在requestId的基础上又加了一层处理。我改完之后对于非标准格式的requestId走MD5分支这个没问题。但问题是我改代码的时候把一个前置的判断条件顺手优化掉了。原来的代码是if (StringUtils.isNotBlank(requestId)) { // 设置traceId MDC.put(traceId, generateTraceId(requestId)); }我重构的时候觉得isNotBlank这个判断跟后面正则匹配的逻辑有重叠就给合并了变成了javaif (requestId ! null requestId.matches(...)) { // 只对标准格式处理 }这样非标准格式的requestId就直接跳过了整个逻辑连MDC都没设置。更隐蔽的是之前那个拦截器的逻辑里即使requestId是空也会用UUID.randomUUID()生成一个兜底的traceId。我重构的时候把这个兜底逻辑挪到了一个我认为更合适的位置但那个位置在某些异常路径下根本执行不到。所以结果就是部分请求的traceId没设置下游服务拿不到traceId就崩了。凌晨两点的感悟问题最终在凌晨两点修复了。改回去三行加了三行注释发版观察了二十分钟一切正常。回家路上我在想一个问题我为什么会在周五下午去动一个看起来可以优化但已经在线上跑了两年的代码答案其实挺简单的——我看到那段正则匹配的时候就难受职业病犯了。总觉得这种写法不优雅性能有隐患应该重构一下。但事实上那个接口的QPS也就200多那个正则匹配即使是最差情况对整个系统的影响也微乎其微。我花了一个小时定位了一个非关键问题然后用一个不那么稳妥的方案修复了它最后引入了一个更严重的bug。你说这事儿怪谁怪测试没覆盖全怪CR没看出来说到底还是怪我自己没守住线上代码能不动就不动这条底线尤其是周五下午四点半这个死亡时间点。写这段文字的时候已经是周六了。我给自己立了个规矩以后周五下午三点之后除了紧急故障任何代码变更都不做。优化代码这种事儿留给周三上午脑子最清醒的时候干。别学我。

相关新闻

第六节:Pinia 状态管理搭建

第六节:Pinia 状态管理搭建

2026/8/30 23:12:25

第六节:Pinia 状态管理搭建目标:搭建 pinia,实现用户信息存储(token、用户名),替代 Vuex,全部使用 setup 语法。 新建两个 store: user.js 用户模块:token、用户信息、登…

京东2016系统测试工程师笔试真题解析:核心考点与答题思路

京东2016系统测试工程师笔试真题解析:核心考点与答题思路

2026/8/30 23:12:25

真题这种东西,放在平时看是几道选择题,放在面试前看就是一份押题宝典。京东2016年这套系统测试工程师的笔试真题,我前前后后给好几个准备校招的朋友讲过,每次讲完都觉得,这套题的价值远不止“刷一遍对答案”这么简单。…

Keil + STM32CubeProgrammer:解决下载失败、读保护与批量烧录

Keil + STM32CubeProgrammer:解决下载失败、读保护与批量烧录

2026/8/30 23:12:25

先说个我印象特别深的场景。有次在客户现场调板子,程序改完点LOAD下载,Keil直接弹了一行红字:RDDI-DAP Error。试过重新插拔ST-LINK、换USB口、换电脑,全都没用。那时候我还没正经研究过“读保护”这回事,最后被逼得翻…

RAG文档解析为何是关键?Cohere Parse低价背后与选型策略

RAG文档解析为何是关键?Cohere Parse低价背后与选型策略

2026/8/31 0:22:27

文档解析这件事,看起来是 RAG 流水线里最没有想象空间的一步。很多人会把精力放在 embedding 选型、chunk 策略、向量库调优上,直到某一天方案部署上线,发现一个上千页的 PDF 根本抽不出干净的正文、表格张冠李戴、页码混进正文,才…

多量程可编程直流电源:选型原理、实测配置与避坑指南

多量程可编程直流电源:选型原理、实测配置与避坑指南

2026/8/31 0:22:27

如果你也和我一样,工位上常年堆着三四台不同规格的直流电源——一台低压大电流、一台高压小电流、再加上一台可调限流的——那你大概也经历过这种场景:测一块12V锂电池板子,刚接上设备却发现手头的电源要么电压不够,要么电流撑不住…

智能体AI实战:从零搭建个人智能体,Dify与Coze工作流全攻略

智能体AI实战:从零搭建个人智能体,Dify与Coze工作流全攻略

2026/8/31 0:22:27

智能体AI 这一轮浪潮里最被低估的一点,是它把 AI 从“生成内容”推进到了“执行任务”。过去我用聊天 AI 只是问问题、写文案、改代码;当我真正开始搭建自己的智能体,事情才开始变得不一样:它能结合我的知识库回答专业问题&#x…

STM32H7 Bootloader V9.2升级实战:双Bank与Cache一致性修复

STM32H7 Bootloader V9.2升级实战:双Bank与Cache一致性修复

2026/8/31 0:22:27

最近在产线上把一批基于STM32H743和STM32H745的板卡从Embedded Bootloader V9.1升级到了V9.2。这次升级不是简单换个版本号,而是把过去半年在生产、现场运维、以及客户反馈中踩过的大大小小的坑,集中做了一次收敛。如果你正在用STM32H7系列做带网络、运动…

AI Skills:从提示词到可复用技能包,重塑AI工作流

AI Skills:从提示词到可复用技能包,重塑AI工作流

2026/8/31 0:22:27

这次我们来看一个正在改变 AI 生产工作流组织方式的东西: AI Skills 。 最近几个月,AI 编程和设计工具圈最热的关键词之一就是 Skills。从 Claude Code、Codex CLI,到 Cursor、VS Code 生态,几乎都在往“技能包”方向靠。它和普…

Sub-1GHz收发器实战:远距离低功耗无线监测方案解析

Sub-1GHz收发器实战:远距离低功耗无线监测方案解析

2026/8/31 0:12:27

做果园环境监测项目的时候,我在 2.4 GHz 方案上吃够了苦头:树冠遮挡严重,30 个节点分布在几百亩地里,网关放在板房旁,最远的节点距离将近 700 米,用 2.4 GHz 跑下来丢包率感人,最后只能靠加路由…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/8/30 0:01:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/30 0:01:07

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/30 0:01:07

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

2026/8/31 0:02:27

接到一个仪表类项目,要在 LAT1189 上输出几种不同波形:正弦、三角、带可调死区的脉冲,频率和幅度都得能实时改。板子上没有 DAC,就一个定时器加几个 DMA 通道。我一开始觉得在定时器中断里改比较寄存器也能应付,后来把…

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

2026/8/31 0:02:27

前两周调试一块带着Cortex-M3内核的板子,IDE里下载固件时突然弹出一行刺眼的错误: error: flash download failed - cortex-m3 。这种报错在嵌入式开发里太常见了,常见到很多人第一反应就是换根数据线、重插一下调试器,但重启三…

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

2026/8/31 0:02:27

做STM32 GUI开发的朋友应该都有体会——界面搭得再漂亮,一旦屏幕切换卡成PPT,整个产品的档次瞬间就没了。早期我在LAT1212这个基于STM32的GUI工程上用TouchGFX做二次开发,最头疼的不是画界面,而是怎么让切换动画既流畅又自然。Tou…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/28 7:35:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/28 7:34:51

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/28 7:34:35

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…