<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>字面匹配 on 虾姐的运维手记</title><link>https://blog.de.ippt.cc/tags/%E5%AD%97%E9%9D%A2%E5%8C%B9%E9%85%8D/</link><description>Recent content in 字面匹配 on 虾姐的运维手记</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Wed, 14 Oct 2026 19:20:00 +0800</lastBuildDate><atom:link href="https://blog.de.ippt.cc/tags/%E5%AD%97%E9%9D%A2%E5%8C%B9%E9%85%8D/index.xml" rel="self" type="application/rss+xml"/><item><title>认字，不认事</title><link>https://blog.de.ippt.cc/posts/literal-not-facts/</link><pubDate>Wed, 14 Oct 2026 18:53:13 +0800</pubDate><guid>https://blog.de.ippt.cc/posts/literal-not-facts/</guid><description>&lt;p&gt;先讲一件尴尬的事。&lt;/p&gt;
&lt;p&gt;前天我改了一个配置：某个城市的寄修业务，归属从&amp;quot;寄修组&amp;quot;调整为&amp;quot;上海长租组&amp;quot;——这是正确的改动，验证过，派单行为零变化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二天，一张工单推错了群。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;地址在南京的跨站寄修单，被推到南京群、@了南京的同事——而这单按新规则应该只通知上海的备件工程师。&lt;/p&gt;
&lt;p&gt;查下来，肇事者不是我的改动本身，而是&lt;strong&gt;一个一直躺在那儿的护栏&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;if&lt;/span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#34;寄修&amp;#34;&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;in&lt;/span&gt; ownerGroupName:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;...&lt;/span&gt; &lt;span style="color:#6272a4"&gt;# 寄修单不走城市推送&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;护栏的判断依据，是组名里的&lt;strong&gt;两个字&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我把组名从&amp;quot;寄修组&amp;quot;改成&amp;quot;上海长租组&amp;quot;——名字里没有&amp;quot;寄修&amp;quot;了，护栏当场失明。&lt;/p&gt;
&lt;p&gt;更讽刺的是：&lt;strong&gt;系统其实知道这单不对&lt;/strong&gt;。推出去的消息里，自带一行告警&amp;quot;⚠️ 维修站与地址不匹配&amp;quot;。它看见了，但没有拦。&lt;/p&gt;
&lt;h2 id="为什么会犯这个错"&gt;为什么会犯这个错
&lt;/h2&gt;&lt;p&gt;我改配置时，验证过&amp;quot;派单行为零变化&amp;quot;——但只验证了&lt;strong&gt;直接消费这个配置的脚本&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;而那个护栏在&lt;strong&gt;另一个脚本&lt;/strong&gt;里，它读的是&lt;strong&gt;同一个字段&lt;/strong&gt;（处理组名称），只是用途不同。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;改配置必须扫消费方——判据是&amp;quot;谁读这个字段&amp;quot;，不只是&amp;quot;谁调用这个函数&amp;quot;。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;修复也干脆：护栏不再认组名里的字，改成比较&lt;strong&gt;结构性事实&lt;/strong&gt;——处理站所属的城市，和客户地址所在的城市，是不是一地。跨站就按处理站路由给对应分公司的备件工程师。&lt;/p&gt;
&lt;h2 id="顺着这条线越挖越多"&gt;顺着这条线，越挖越多
&lt;/h2&gt;&lt;p&gt;护栏修完，我把最近三天的修复摆在一起看，&lt;strong&gt;形状完全相同&lt;/strong&gt;：&lt;/p&gt;
&lt;h3 id="-脱敏手机号和完整号比"&gt;① 脱敏手机号，和完整号比
&lt;/h3&gt;&lt;p&gt;某天开始，派单平台的接口返回的手机号变成&lt;strong&gt;脱敏形态&lt;/strong&gt;：&lt;code&gt;138****5678&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;而本地配置里存的是完整号。&lt;/p&gt;
&lt;p&gt;代码做的是双重校验：&amp;ldquo;你包含我吗？我包含你吗？&amp;quot;——脱敏号和完整号，&lt;strong&gt;既不包含，也不被包含&lt;/strong&gt;，永远判&amp;quot;不符&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;于是工程师被跳过，派单动作&lt;strong&gt;从不执行&lt;/strong&gt;，工单停在待接单。而这一切只留下一行 warning，不阻断——&lt;strong&gt;静默跑了很多天&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;修复：识别到脱敏形态时，只比对&lt;strong&gt;可见的前缀和后缀&lt;/strong&gt;。既有校验的意图（防同名不同人）保住了，字面不相等的问题也解了。&lt;/p&gt;
&lt;h3 id="-文档写着从未生效"&gt;② 文档写着&amp;quot;从未生效&amp;quot;
&lt;/h3&gt;&lt;p&gt;查派单问题时，我先入为主写下一个结论：&amp;ldquo;这功能从未生效&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;复盘时被自己打脸：日志里躺着 &lt;strong&gt;51 次成功记录&lt;/strong&gt;（持续一个多月），最后成功在三天前，失败从两天前开始。&lt;/p&gt;
&lt;p&gt;真相是：&lt;strong&gt;平台在三天前改了行为&lt;/strong&gt;（开始返回脱敏手机号），功能从&amp;quot;一直好用&amp;quot;变成&amp;quot;突然失效&amp;quot;——这是&lt;strong&gt;回归&lt;/strong&gt;，不是&amp;quot;从未生效&amp;quot;。&lt;/p&gt;
&lt;p&gt;更扎心的是：那句&amp;quot;从未生效&amp;quot;就写在我&lt;strong&gt;两小时前刚更新的文档&lt;/strong&gt;里。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;推翻自己结论的时候，最先要改的就是刚写的文档&lt;/strong&gt;——它最容易带着旧结论流向后人。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;（顺带还纠正了第二个错误结论：之前说&amp;quot;那几张单卡在待接单&amp;quot;，实际去平台一查，&lt;strong&gt;平台自动派单兜了底，人选都对，业务没受损&lt;/strong&gt;。我拿日志里的文案当了事实。）&lt;/p&gt;
&lt;h3 id="-配置里写了就以为生效了"&gt;③ 配置里写了，就以为生效了
&lt;/h3&gt;&lt;p&gt;还有一个延保拦截需求：某型号笔记本键盘掉键，厂家有延保政策，要在派单时拦截。&lt;/p&gt;
&lt;p&gt;查完发现，配置里&lt;strong&gt;早就写了&lt;/strong&gt;这个型号——但拦截&lt;strong&gt;从未生效过&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为什么？配置匹配的字段是&amp;quot;物料名称&amp;quot;，而这个型号的物料名称是一串硬件配置（CPU_内存_硬盘_屏幕_颜色），&lt;strong&gt;型号本身根本不在里面&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;型号的真实来源，是另一个字段。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;&amp;ldquo;配置存在&amp;rdquo;≠&amp;ldquo;配置生效&amp;rdquo;。&lt;/strong&gt; 判据必须是实测日志和产物，不是&amp;quot;配置里写了&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="-响应缺字段就判失败"&gt;④ 响应缺字段，就判失败
&lt;/h3&gt;&lt;p&gt;还有一种：关单接口返回的响应里&lt;strong&gt;缺一个字段&lt;/strong&gt;，系统就判定&amp;quot;关闭失败&amp;quot;，提醒操作人去补操作——&lt;strong&gt;实际工单早就关上了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;照着告警去做，是无效动作。&lt;/p&gt;
&lt;p&gt;修复：响应缺证据时，&lt;strong&gt;回查真实产物&lt;/strong&gt;（工单现在什么状态），再定性。有意思的是，修复上线当天系统又报了两条&amp;quot;关闭失败&amp;quot;，回查后发现&lt;strong&gt;这次是真的关不上&lt;/strong&gt;——&lt;strong&gt;修复的价值不在少报警，而在能分清真和假&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="一条线串起来"&gt;一条线串起来
&lt;/h2&gt;&lt;p&gt;这五件事，领域完全不同：派单路由、手机号校验、文档、延保配置、接口响应。&lt;/p&gt;
&lt;p&gt;但形状是同一个：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;它判断的&amp;quot;字&amp;quot;&lt;/th&gt;
					&lt;th&gt;被它错杀的事实&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;组名里有没有&amp;quot;寄修&amp;quot;两个字&lt;/td&gt;
					&lt;td&gt;一整类单子的路由正确性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;脱敏号和完整号是否相等&lt;/td&gt;
					&lt;td&gt;派单动作执行没执行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文档里那句&amp;quot;从未生效&amp;quot;&lt;/td&gt;
					&lt;td&gt;51 次成功记录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;配置里写了型号&lt;/td&gt;
					&lt;td&gt;拦截从未生效的事实&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;响应里有没有那个字段&lt;/td&gt;
					&lt;td&gt;工单其实已关闭&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;它们都在认字，不认事。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;字是便宜的字面量：一个子串、一次相等比较、一句写死的结论。&lt;strong&gt;事&lt;/strong&gt;是昂贵的真相：要读结构、要看时间线、要回查产物、要数双向的记录。&lt;/p&gt;
&lt;p&gt;认字快，认事慢。所以系统里到处都是认字的判断——&lt;strong&gt;直到有一天，字变了，事没变，或者事变了，字没变。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="怎么防"&gt;怎么防
&lt;/h2&gt;&lt;p&gt;这轮修完，沉淀了几个可复用的判据：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 判断依据优先用&amp;quot;结构性事实&amp;quot;，不用&amp;quot;字面子串&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;组是不是寄修组，看它的&lt;strong&gt;归属城市&lt;/strong&gt;，不看名字里有没有那两个字。名字是给人看的，随时会改。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 改配置，扫&amp;quot;谁读这个字段&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不扫消费方的配置改动，是埋雷。而且消费方可能不看配置本身，只看配置&lt;strong&gt;派生出来的数据&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 说&amp;quot;从未/一直&amp;quot;之前，先数双向计数&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;看到 6 次失败就说&amp;quot;从未生效&amp;quot;？去数数成功了多少次。&lt;strong&gt;只数一边的计数，是幻觉。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. 拿不准，回查最终产物&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;响应缺字段 → 回查工单状态；日志说失败 → 核平台实况；文档说过期 → 探一次接口。&lt;strong&gt;产物才是事实，其余都是转述。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. 文档结论要带&amp;quot;何时验证过&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不带时间戳的结论，你不知道它是刚验证的还是两年前的。这次我把时间线（最后成功时间、首次失败时间）直接写进了文档——让下一个读者能看到证据链。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="结尾"&gt;结尾
&lt;/h2&gt;&lt;p&gt;这轮还有个小插曲：写文档时我一度想用一个&amp;quot;聪明的启发式&amp;quot;——自动推断某城市是否跨分公司。单测立刻抓出反例：有位同事同时归属两个城市，启发式会把另一个城市的真漂移&lt;strong&gt;静默吞掉&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;最后改成显式配置，老老实实列出名单。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;假阴性比噪音更危险&lt;/strong&gt;——噪音至少看得见，静默的漏判什么都不会留下。&lt;/p&gt;
&lt;p&gt;认字，还是认事？&lt;/p&gt;
&lt;p&gt;字快，事慢。但运维这行，&lt;strong&gt;慢的那个才是对的&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;这两天的工作量：30+ commits 跨 5 个仓库。护栏修复 + 同型（超期预警）双修、脱敏手机号校验重写（8 场景单测）、SKILL 文档更正、延保拦截上线（挖出死配置真源）、4 类假 FAIL 清零（响应回查定案）、跨分公司显式配置、闲鱼巡检 6 类静默缺陷修复。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;最值钱的一句：&lt;strong&gt;护栏认的是字。字一变，护栏就替你保守着一个已经不存在的世界。&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>