上游数据不对,正确动作是先停服务再解释|洹拓科技

一、暂停一个对外功能是有语义的工程动作
一则公告被公开报道:某厂商宣布暂停手机端的一项灾害预警功能,给出的原因是合作第三方出现“异常偏差”,后续分两个阶段推进——先完成新版服务的功能适配与测试,再向存量机型陆续推送系统更新。我们不去评论这家厂商的处理是否得当,来源没给偏差的具体内容与影响范围,任何推测都没有意义。值得抄的是它暴露出来的那条判定链路:一家公司愿意把一个已经对外承诺的高危功能停掉,说明它内部认定数据质量已经低到不能保证结论方向正确。
多数团队没有这条链路。我们的默认假设是可用性优先,功能挂了就重启、就重试、就降级显示,数据不对则加个“仅供参考”了事。要把“停”变成一个可执行动作,先按结论风险把功能分档。
| 档位 | 典型功能 | 允许的处置 | 触发指标 |
|---|---|---|---|
| 仅供展示 | 报表、趋势图、历史统计 | 标注口径与更新时间即可继续提供 | 未标注质量状态才算违规 |
| 影响用户决策 | 调度、补货、告警升级、行程变更 | 结果上强制显示数据质量,并限制自动触发 | 多源结论矛盾或置信字段缺失即降级并预警 |
| 导致人身或财产动作 | 预警推送、支付指令、设备控制 | 直接停,不设容忍阈值 | 只要无法保证结论方向正确即触发 |
分档的依据不是“错得多不多”,而是单条结论会不会直接触发不可逆动作。展示类错了,用户可以靠别的渠道校正;预警类错了,一次方向错误没法靠后面出现的正确结论补偿,因为动作已经做完了。第三档的判据必须是二值的,因为“偏差在可接受范围内”这种说法在不可逆动作面前没有操作性。
二、“异常偏差”有四类可观测信号
上游质量出问题从来不是无声的,只是我们没有把它做成监控项。四类信号,按实现成本从低到高排。
时间戳与序号不连续。校验时间戳单调性、时钟跳变、序号回退与重复。这一类最便宜,也最容易被跳过,因为它不需要理解业务,只需要按字段做规则检查。它偏偏是最早出现的信号——上游在改数据链路时,序号规则总是先出问题。
更新延迟或缺号。要维护“应有条数与实际条数”的差值,对上游做完整性核对,缺号直接当质量事件处理,而不是等下一批数据来补齐。延迟要区分两种情况:整条管道断了和上游在批量补数据,前者的处置是停,后者的处置是标记数据仍在回填。
数值分布偏离历史区间。按事件类型维护分位数带,超出带宽报警。这条只能预警不能定性:真实世界本身会突变,一次大规模变化也会把分布推出历史带。所以它的正确用法是提高其他信号的敏感度,而不是单独作为停服依据。
同一事件多源结论互相矛盾。两个来源对同一事件给出不同方向,或量级差异超过设定带宽。这条最接近“结论错了”,但也是最贵的,因为要预先接入彼此独立的来源,还要把比对做成常态任务而不是事后抽查。
四类信号的共同要求是落表:每一类都要有观测记录、阈值、触发起点与人工确认结论。没有落表的报警,在停服决策时等于没有证据。
三、三条补救为什么在这类功能上不够
默认反应通常是先救而不是先停,下面三条最常见的补救各自有前提。
第一条是多源交叉验证。它成立的条件是来源真的彼此独立。两个源来自同一上游、或来自同一套采集体系时,交叉验证只是把同一个错误读了两遍。工程上要做的是把独立性写进依赖清单并定期复核,否则多源只是个好听的结构。
第二条是按置信度降级、不暂停。问题在于置信度字段往往是上游给的。上游的数据链路出问题时,这个字段本身也可能是错的——用被污染的数据来判断数据是否干净,逻辑上不成立。置信度降级只在我们自己能独立算出置信度时才有意义。
第三条是限制高危动作、只保留提示。听起来稳妥,实际是把责任转移给用户:界面仍然显示结论,只是不再自动触发,用户照旧会把提示当结论行动。行为没有改变,风险只是换了归属。
这三条在展示与决策类功能上确实够用,也正是我们该先试它们的理由——停一个功能的代价不只是开发成本,还有用户转向更不可靠信息源的风险。但对结论方向不可保证的第三档功能,试完这三条仍不能把风险降到可接受,剩下的正确动作就是停。敢停不等于能力差,把它当成故障来处理才是能力问题。
四、停服决策要落到四个字段
把“停不停”从临场判断变成流程,需要四个字段,缺一个都会在真出事时卡住。
谁有权停。停的权限要下放到值班负责人,让他能在无人会签的情况下执行;恢复的权限可以上收,由功能负责人和数据负责人共同确认。理由很直白:停是可逆动作,恢复不可逆的风险更大,权限配置要按这个不对称来设计,而不是反过来。
依据什么判据。写进运行手册的具体条件——哪一类信号、连续若干个观测周期、影响落在哪一档,全部固定。判据临时讨论的结果永远是“再观察一下”。
停的范围按什么划。三种粒度各有代价:按功能停最干净,也最容易漏掉间接依赖这个功能的下游;按机型或版本停能保住一部分用户,代价是要维护两套行为;按地域停最危险,边界判定出错会把不受影响的区域一起关掉,或者反过来。要给一个默认档位和升级路径,默认按功能停。
停之后多久必须复审。这是最常被漏掉的一项。没有复审时限的暂停会变成无人负责的长期状态:入口挂着旧文案、公告过期、下游系统各自猜。时限要按功能档次给,高危功能的复审周期应该短到能在一个迭代内完成一次判断。
五、公告四段结构与停服期间的四项义务
公告不是致歉信,是在有限信息下替用户做决策。四段结构,顺序不要调换。
第一段,发生了什么。只写可确认的部分:上游数据出现异常,我们暂停了某功能。不要推测原因,不要写“疑似”。第二段,影响谁。机型、系统版本、区域、功能范围说清楚,特别要区分存量用户与新用户的差别,因为这直接决定谁会以为功能从未存在过。第三段,现在该怎么办。给出替代动作,并且必须写一句“请不要依赖此功能做重要决定”。这句话不好看,但公告的作用是降低用户损失而不是维持使用量,省掉它的团队通常是在维护指标而不是维护用户。第四段,什么时候恢复与如何得知恢复。没有确切日期就给阶段与状态查询位置,不要给一个到期的空承诺。
停服期间的义务比公告更容易被忽略,四项要有清单:入口不能消失,但状态必须明确标注,消失的入口会让用户反复检查自己的设置,把工单打满;不得留下旧的结论内容,任何缓存的历史结论都会被当作现行结论使用;要有可达的反馈渠道,用来收集“哪些人因此受影响、影响成什么样”;把用户自建的通知需求记录下来,有人主动来问能不能短信或邮件兜底,这本身就是恢复优先级的依据。
六、恢复的三条判据与一张长期台账
恢复比暂停难,因为暂停只需要判断“不能保证”,恢复要给出“能保证”的证据。三条判据。
一是上游质量恢复到什么水位算可复。要写成具体指标与持续时长,比如四类信号全部回到阈值内并连续保持若干个观测周期,而不是接受一句“上游已确认修复”。二是在影子运行下比对新旧两版逻辑。新版适配与测试期内,让新旧逻辑并行跑若干天,只比对结论、不对外可见,差异逐条归因,确认差异来自修复而不是新问题。三是灰度机型与回退条件。先放小范围,把回退触发写死——只要偏差信号重新出现即回退,不需要开会。
恢复公告要连同末次误停的复盘一起发:如果暂停判据本身需要修订,就写进去。承认判据需要改,比只发一条恢复通知更能建立长期信任。
最后是我们自己该立刻做的一件事。凡对外承诺的功能里,凡结论来自第三方数据的,单独建一张台账,字段固定:功能名、数据来源与提供方、独立性判断结论、质量信号与阈值、可停性、停后的降级形态、公告模板位置、授权停与授权复的人、复审周期。按固定周期复核一次。这张表的用处是把“停”从一次临场争论变成一次查表——洹拓的项目里,它和应急预案同级归档。多数团队承诺的是可用性指标,而真正决定用户损失的是数据质量,台账就是把这句话变成可执行的东西。