案例 小程序图片上传失败排查:用 code=400 分布和 route_name 收敛到微信基础库灰度

2026-11-09 00:04:34

小程序图片上传失败排查:用 code=400 分布和 route_name 收敛到微信基础库灰度

2 月 10 日,好大夫部分小程序用户投诉上传图片失败。10 多人参与,排查三天。最终结论:微信在 2 月 9 日下午升级基础库,灰度 1% iOS 用户,2 月 11 日回滚;部分用户仍有异常,需要清理缓存。

排查过程:先切责任段,再看分布

按请求链路拆四段:用户侧、运营商传输节点、Kong 入口网关、后端图片服务。上传失败可能落在任一段。先做差异对比:同一用户切换网络仍失败;切到好大夫 APP 能上传成功。前端据此判断不是用户侧网络问题。Kong 日志里,部分用户重试多次都是 code=400。

怀疑链路传输:我们有多家网络节点运营商,切链路、直接回源后问题仍在。抓包并与运营商技术一起排查,未明确原因,运营商反馈仍是用户侧问题。

怀疑小程序版本:2 月 9 日有业务方向上线小程序,改的是 http2 相关,时间点对得上。紧急上线更新包,用户更新后问题依然存在。

怀疑 Kong 进程:2 月 11 日晚重启 Kong,担心进程启动太久、垃圾未回收。第二天问题未缓解。

对比最近几天 code=400 占比,2 月 10~11 日比之前多一倍;code=400 的 route_name 基本集中在小程序侧上传图片接口。范围收敛到小程序端后,联系微信社区、微信内部开发。2 月 13 日下午反馈:2 月 9 日下午微信升级基础库,灰度 1% iOS 用户,2 月 11 日回滚,部分用户还有异常需清理缓存。

判断顺序不是从组件开始猜,而是先用差异定位责任段:切网络失败、切 APP 成功,排除用户侧网络;切运营商链路和回源无效,排除传输节点;重启 Kong 无效,排除网关进程;2 月 9 日 http2 改动更新包后仍存在,排除该业务发布。再用 code 与 route_name 分布收敛:code=400、重试仍 400、route_name 集中传图接口,指向终端请求构造/基础库行为,而不是后端处理能力。最后才落到微信基础库灰度。

请求链路的四个责任段

  • 用户侧:机器内存不足、小程序闪退;网络不稳定;上传过程中切到后台,重新唤起续传失败。
  • 网络节点:请求到源站入口网关前先走运营商传输节点;传输节点对接多家运营商,传输不稳定或命中防火墙策略会失败。
  • 入口网关 Kong:路由策略配置异常、Kong 节点异常、某个 upstream 节点异常都会失败。
  • 后端图片服务:处理能力不足、负载高、进程夯住或其他异常会失败。

排查时先判段,再在段内看指标。

异常定位建模

异常定位要在参照系里做:把 SLI 波动可视化,比较不同 SLI 的波动振幅差异,推断可能原因;给异常建模并关联到可观测 SLI,透过 SLI 表象反查异常原因。提效的第一步是量化异常,让异常可观测;第二步是界面引导定位。

上传图片场景的 SLI

“两点一线,分两面,一面监控画像,一面异常定位”。梳理请求开始到结束,抓住两点连成一线。SLI 参考 Google VALET:Volume、Available、Latency、Error、Ticket。

SLO 两种设置:

  • 固定阈值:按经验设,如 QPS 峰值不得大于 10k。
  • 相对值:如 code=404 环比增加 20%。

为了异常可观测,按不同维度细分 SLI。这次上传图片异常因微信灰度特定基础库,改造后收集终端信息:设备平台、设备型号、微信版本、微信基础库版本、小程序版本。

落地改造清单

用户侧:

  • 每次小程序启动发探包请求,上报平台、版本、微信版本、微信基础库版本、小程序包名、小程序版本;不收集隐私。
  • 通过 hash 生成版本信息指纹 hash_key;后续请求 URL 和 HTTP header 携带。
  • 通过 hash_key 关联 Kong 日志和版本信息,提炼终端不同维度 SLI。
  • 小程序每次请求生成 trace_id,通过 header 透传。
  • 网络不佳时先把 Error 日志暂存到 LocalStorage 队列,有网再上报;所有记录日志都带 trace_id。

网络节点:

  • 新增运营商标识,方便对比不同运营商传输可用性。
  • 收集运营商日志存储到 Clickhouse,让传输节点可观测。

入口网关:

  • 按业务类型拆分 route_name,如上传、订单提交等。
  • route_name 支持打标签:业务部门、所属页面;用于告警监控和识别风险,通知到具体部门。
  • 插件支持生成或透传 trace_id,打通 KongLog 和后端 TraceLog。

后端服务:

  • 增加日志埋点,分析不同图片尺寸上传下载指标。
  • 定义好不同 code 码。

数据与看板:

  • SLI 存储到 Clickhouse,可视化基于 Grafana 写 SQL。
  • 新增地理位置分析,将请求 IP 转经纬度。

改造中遇到的问题

  • 控制 Error 信息大小。单条信息过大会导致 Flume 收集异常,出现重复收集或丢失日志。
  • 采样上报,控制频次。异常可能连锁反应,瞬时大量日志,避免频繁上报消耗用户带宽。
  • 降噪处理。腾讯周期性安全扫描会产生干扰异常,如 499,影响用户维度 SLI 准确性,需要识别干扰降噪。
  • 提升分析性能,简化 SQL。很多分析要连表查询,数据量增大有性能问题;添加大量视图,重建不同维度索引表,将数据按分钟维度聚合成 SLI,避免查询原始日志的性能开销。

看板与判断路径

  1. 小程序分析首页:大盘投屏;上部分最近 15min 瞬时数据,大于经验阈值标红;下部分长期趋势,比对同比环比,面板支持下钻。列出最关心的 SLI,如 QPS/UV、慢路由请求数、异常请求数;根据时延和 ErrorCode 分布下钻。
  2. 长期趋势分析:最近 1 周/1 月/1 年宏观趋势,结合上线计划分析节点前后变化。
  3. Code 异常分析:首页观察异常 code 分布,下钻到具体 code 分析页。
    • 是否需要人工介入?假定 SLO 为 code=400 错误率<0.5%,p = total_400_request / (total_200_request + total_400_request)。如 code=200 访问量 10K,400 达到 500 则需人工介入。
    • 同比环比是否有差异?分析当日请求判断是否突发,分析一周判断是否周期性。
    • 是否有路由差异性?大面积无异常报错还是特定路由异常。
    • 异常特征是否有终端平台、微信版本、微信基础库版本、小程序版本差异性?
    • 差异显著性判断有认知误区:iPhone 异常数比 oppo 大,很可能是 iPhone 总体访问基数大,此时看各自长期占比趋势。
  4. 慢路由风险分析:关注 Top10 慢路由,分析长期慢还是突发抓取慢,结合 APM 链路分析。
  5. 路由详情分析:code 分布差异(如 P99 时延增加可能是 code=304 缓存命中过低);同比环比差异,首要怀疑线上变更;是否抓取造成,分析 UA(hash ua)与 ClientIP 占比;地域差异;运营商节点差异;后端节点差异。
  6. 抓取分析:判断 UA 和 ClientIP 访问占比,抓取特征为单个 UA 访问量突增、ClientIP 集中,结合 QPM 长期趋势判断。

推荐文章

程序员茄子在线接单