第四十六章 · 平静¶
排查脚本周二早上七点四十一分跑完。二十四条未知原因,二十三条落进超时和金额不一致的交叉区。剩一条,不在任何分类里。
SD-20261219-10447。JPY/CNY。transaction_amount 二百万日元,settlement_amount 六万七千零四元。按十二月十九日中间价折算,应为六万八千二百三十一元。差一千二百二十七元,偏差千分之十八。
其余四百二十二笔失败,金额偏差没有一笔超过千分之五。
他把这条单独拉出来,跑链路日志。十一个节点,逐段对时间。第九个节点,fx_rate_snapshot 查询返回空——十二月十九日的快照不存在。历史汇率只保留三天,十二月十九日之后的第二十四天。
日志里下一行写着:fx_snapshot_missed, fallback=default_rate。
用了默认汇率。哪来的默认汇率,代码注释里没有写。
他查了这笔交易的发起方。商户号 M-B-2214,跨境电商,去年十一月接入,月均交易四百笔左右。这一笔是两百万日元,是这个商户十二月最大的一笔。
记事本:「SD-20261219-10447,差一千二百二十七元。快照缺失,用了默认汇率。默认汇率哪来的,查不到。」
写完他坐了一会儿。这笔要是报上去,万钧第一个问题会是:只差一笔,还是有一类。他答不出来。答不出来的时候报上去,上周说的「预计翻倍」就要重新校准。
他把记事本合上,先给刘铮发消息:「剩的那条不落在已知分类。金额偏差千分之十八。链路日志里汇率快照缺失,用了默认汇率。」
八分钟后刘铮回:「默认汇率?哪来的默认。」
「代码里没写来源。」
「我问问商务,合作方的汇率源是谁在维护。你别先报万钧。查清楚这条是孤例还是一类,再报。」
陈稳回了一个「好」。
九点十分。赵岩的消息:「存储扩容走完了。一号库 fx_rate_snapshot 从周日凌晨开始回补三十天历史汇率。下周一你能查到十二月十九号的快照。」
下周一。他把这个日期抄在记事本上,抄在那一行差的后面。
上午十一点。他申请了一号库的只读权限,走审批。权限页面加载出来的时候,他顺手翻了翻运维工单列表。
DB-20261028-0047。那条工单。状态一栏写着:已归档。
归档时间是十二月三十日。操作人一栏是空的。他点了详情,详情页只有一行系统备注:「工单超期未跟进,系统自动归档。」
系统自动归档。他记得那条工单是周其正提交漏洞工单之后,赵岩建的跟踪单,里面挂着 DHCP 全量操作日志的分析结论。一千八百四十七条日志,删索引那一条的来龙去脉都在里面。
现在它归档了。超期未跟进——最后一次跟进记录停在十一月四日。
陈稳把页面关了。工单列表往下翻了两页,又翻回来,把那条工单的编号抄进记事本。抄完,在编号后面画了一个括号,括号里写:谁批的归档。
没有答案。他把笔帽扣上。
下午三点。商务那边回了话,经由刘铮转过来:合作方的汇率源是他们财务系统每天早上九点推的 CSV,推到恒澜的接入网关。快照机制是恒澜这边自己做的,负责的人,刘铮发来一个名字——万征。
万征。数据平台的,接了张磊推广对接的那个人。汇率源落在接入网关,网关侧的快照落库是他维护的。
陈稳打开万征写的汇率同步服务代码。一千四百行 Go。default_rate 定义在第八百二十一行:
上一成功快照。十二月十九日往前找,最后一个成功快照是十二月十六日的。十二月十七日到十九日,汇率同步任务连续三天失败,失败原因:合作方 CSV 推送延迟,超过当天截止时间。
三天。汇率差千分之十八,不是这一笔写错了,是它结在了一个没有快照的窗口里。
他把十二月十七日到十九日所有走 JPY/CNY 的成交拉出来。一共五十一笔。其中四笔失败,四十七笔成功。四十七笔成功的,全部按十二月十六日的快照折算。
四十七笔里,有多少笔的实际偏差超过千分之五,要等下周一快照回补完才能算。
他又往前查了同步任务的历史失败记录。日志只留九十天,再往前没有了。九十天里,汇率同步任务失败过六次,每次一两天,都走了兜底。这六次窗口里结了多少笔、每笔偏差多少,同样查不了——日志没有,快照也没有。
记事本上多了一行:「不是一笔的事。是一个窗口的事。窗口里有多少笔,周一才知道。」
再上面一行,补了一句:「兜底机制上线以来没有触发过告警。偏差千分之十八,不告警。因为系统不知道自己错了——它以为自己用的是快照。」
他盯着这两行字。这笔账要是算出来大,万钧在资源会上批下来的三个资源,就批晚了一个月。
四点二十。他给万征发了消息,附上那笔交易的 ID,问兜底值是什么时候配的。万征六分钟后回:「我接手的时候就有。配置文件里写着,没人动过。要不要我查一下配置的 git 历史?」
「查。」
「好。明天给你。」
七点二十。到家。玄关的灯亮着,何晚把灯换了暖光的那档。
鞋柜第二层放着一个纸箱。箱子开着,里面是他的皮鞋——四百八那双,鞋尖的皱褶比刚买的时候深了两道。旁边摆着一双新的,鞋楦还没拆。
「回来了。」何晚在厨房里。「鱼好了。今天的鱼没蒸老,我看了表,八分钟就关火。」
桌上摆了两副碗筷。
他洗手,坐下。鱼上面铺着葱丝,热气往上走。
「中午没吃好。」何晚把鱼转了个方向,鱼背对着他。「多吃点。」
他夹了一筷子。是嫩的。
「你今天回来得早。」他说。
「我周四要带学生去市里比赛,今天把卷子都改完了。」何晚给他盛饭。「所以今晚不赶。」
吃到一半。何晚把筷子放下,搭在碗沿上。
「陈稳。」
他抬起头。
「我们分开吧。」
厨房里抽油烟机还开着,嗡嗡的声音很匀。他伸手把它关了。屋里一下子很静,静得能听见鱼汤在盘子里凉下来的那种没有声音。
「为什么。」
「不是为什么。是这半年,我一直在等一个能说出来的为什么。等到今天,我发现不用等了。」何晚的声音跟平时一样,跟她说「做排骨」的时候一样。「你上上周回来,鞋穿反了方向,你自己不知道。你坐下先开电脑。我跟你说话,你答了,答的是下周的排期。」
他把筷子放在桌上。摆齐了。
「我数过。」何晚说。「十一月到现在,你在家跟我说的话,加起来不到两百句。有一半是单字的。还有几回,你答的内容跟我的问题对不上——你答的是你心里正想着的那件事。你不知道你答错了。」
「我知道。」
「你知道。」何晚点了一下头。「你以前不知道的时候,还会问我一句'今天班里怎么样'。现在你知道了,你就不问了。你觉得知道,就等于说过了。」
他说:「是我不对。」
「你不承认不对的时候,也说这句。」何晚端起碗,把剩下的半碗饭吃完了。吃得很慢,很平静。「我等这句话等了三个月。它每次来的时候,我都在想,下一次会不会多一句。没有。」
他把碗里的饭吃完了。一粒不剩。他不知道自己为什么要吃完,但吃完了。
「十一月你发烧,三十八度二。你说不用管,然后开电脑修了一个 bug。」何晚把碗收进水池,没有开水龙头,手扶着池边站着。「我坐在旁边看了你四十分钟。你修完了,抬头问我几点。不是问我'等很久了吧',是问几点。你在算你还有多少时间。」
她转回身,擦了擦手。
「我那天想,他不是不爱。他是把这个放在了排序的后面。放得很稳,很合理,像一个排期。我不怪一个排期。但我不能嫁给一个排期。」
「婚期,」何晚开始收拾碗,「我原本答应我妈,春节回去把日子定了。我现在去说推迟。」
「好。」
「票我买了两张。一月二十七号的。要是到时候你不想去,退了就行,开车前都能退。」她把碗摞起来,端进厨房。「水开了,你把药吃了吧。抽屉里还有半盒。」
水壶在灶上响。他坐在桌边,看那张空了的桌面。鱼吃掉了大半,葱丝塌在盘底。
「何晚。」
她从厨房探出半个身子。
「今天的鱼很好。」
她看了他两秒。「我知道。」她说。「我每次都想做好的。」
水壶开了。她回去关火。他打开药盒,倒出两粒,就着温水吃了。
九点半。书房。
他打开订票软件。一月二十七日,K1074,两张下铺,到站是她老家的那个小站。出票状态:已出票。退改规则:开车前均可退。
他的拇指停在「订单详情」上。停了很久。
屏幕暗下去了。他没有再点亮。
他打了六个字:「今天的鱼很好。」收件人是她。发出去要两秒。他按了取消,退出来,把手机翻过去扣在桌上。
手机屏幕朝下,桌面上映不出光。
记事本翻开。今天这页已经有了三行。他在最下面加了第四行:
「周一:fx_rate_snapshot 回补完成后,算十二月十七日至十九日 JPY/CNY 全部成交的实际偏差。SD-20261219-10447 单独复核。」
写完这一行,他又写了一行,写得很慢:
「她说过,做和说不知道哪一个对。今天两边都没有做对。」
写完,划掉。纸面上留了一道笔痕,字还能认出来。他没有涂黑它,合上了本子。
客厅里,行李箱的轮子在地上滚了两下,停了。拉链拉到头,声音很短。然后是洗手间的水声,然后是卧室的灯灭掉的声音——开关按下去有一声轻响,他听了三年,听得出来。
他坐到十一点四十。排查脚本的终端还开着,光标在那条交易记录上闪。
SD-20261219-10447, JPY/CNY, 2000000, 67004.00, fx_snapshot_missed
他把这一行复制下来,贴在记事本里那道笔痕的下面。一个是纸上的,一个是屏幕上的。都还没有答案。
周三。早上九点。万征的消息:「配置 git 历史查完了。兜底值是二〇二四年八月配的,配置人已经离职。之后没有改过。」
二〇二四年八月。这个服务上线的时候,就没有人想过快照会缺三天。
十点。刘铮在工位边上停下来。
「万钧今早问我二十四条的进度。我说二十三条确认,一条在查。他说了一句话,我原样转给你——『一条也要查。查清楚是一条还是一类。』」
「下周一能查。」
「他给你留到周一。」刘铮说。「还有个事。商务确认合作方那边的 CSV 推送延迟是他们的财务系统改版导致的,十二月十七号开始,二十号恢复。也就是说那个窗口就四天,不会再开了。但窗口里结了多少笔,还是得等回补。」
「嗯。」
「你昨天怎么了。」刘铮看了他一会儿。「从昨天下午开始,你打字的时候不出声。以前你打字会出声的,很轻,但是有。」
陈稳的手指放在键盘上。
「家里的事。」
刘铮等了一秒,没有接着问。「那笔要是算出来是大数,你打算怎么报。」
「先算。算完再想。」
刘铮走了。终端里,周日的回补任务排上了队,状态显示:pending。排在它前面的还有一个报表任务,预计周日凌晨两点跑完,两点到四点是回补窗口。
四天。窗口四天。回补两天。他两天后能知道那四天里欠了多少。
中午。食堂。他端着餐盘在靠窗的老位子坐下——万钧第一次跟他说话的那张桌。桌面换过了,旧的纹路没有了。对面的椅子空着。
他吃了半碗,放下筷子,把十二月十七日到十九日那四天在心里过了一遍。十二月十九日,周日。那天下午他在结算组的工位上核对汇金线的数据口径。那时候 fx_rate_snapshot 的同步任务正在失败,商户的钱在按三天的旧汇率折算,谁也不知道。
他那天想的是四十三万两千笔的事。同一栋楼里,另一笔账在错,隔了四层楼。
他把剩下的半碗饭吃完了。
下午。他收到赵岩的消息,只有一句:「汇率回补的事办完了。验收单我发你邮箱,你签个字回我。」
他打开邮箱。验收单在收件箱第二封。第一封是行政发的,标题:「员工档案信息年度核对——请于本周五前确认」。
他先签了验收单。回信的时候,手指在键盘上停了一下,打了一行:「上次那件事,谢谢你。」
赵岩回得很快:「不用谢。到了新地方,往前看。」
往前看。他想起周其正说过的那句——你走了之后,也不会有人回答。不对,那是何晚说的——不对。他把两句话在脑子里对了一遍,对不上。哪句是谁说的,他记混了。只有一件事没有混:那张工单归档了,操作人那栏是空的。
他把邮箱关了。
晚上七点五十。到家。
玄关的第二双拖鞋不在了。鞋柜第二层的纸箱还开着,皮鞋在里面,新的那双也在。厨房的置物架上,她常用的那只砂锅不在了,锅架上空出来一个圈。
客厅里她的东西少了三分之一。书架第三层空了一格,格板上有一道浅色的印子,书放久了留下的。阳台上的薄荷搬走了,花盆底下那个接水的白瓷碟还留在原地,碟底有一圈水渍。
行李箱不在了。她说周五来搬剩下的。
他把外套挂好。鞋柜上放着两张火车票,用一根橡皮筋捆着。K1074,一月二十七日,两张下铺。票面朝上。
他站了一会儿。然后把票拿起来,进了书房,拉开背包最里层的夹层。结算组的便利贴在里面,顾源那张打印件在里面。他把两张票放进去,拉链拉上。
书桌上,记事本翻在今天那页。笔痕下面贴着那行从终端复制来的交易记录。
他重新坐下,打开终端。回补任务的状态还是 pending。他写了一个校验脚本的第一段——回补一完成就自动算偏差,不用等他到工位。写到一半,停下来,在文件开头加了注释:
// 十二月十七日至十九日 JPY/CNY 全量偏差核算
// 前提:fx_rate_snapshot 回补完成(周日 02:00-04:00)
// 产出:偏差超过千分之五的笔数、涉及金额、涉及商户
保存。他关掉台灯之前,又看了一眼鞋柜的方向。玄关的灯是暖光的,照着那个开着的纸箱。
抽屉里还有半盒药。他数了数,还剩七粒。
他按时吃了两粒。
← 第四十五章 恶心 · 目录 · 第四十七章 一整夜 →