2. 错误码设计原则:HTTP状态码类比、业务错误码分类、错误码与错误消息分离

在分布式系统与微服务架构中,错误码是服务间通信的“通用语言”。设计一套清晰、可扩展的错误码体系,能够显著降低排障成本、提升断言效率,并为发布回滚提供精确的触发信号。本节从三个核心维度展开:HTTP状态码类比、业务错误码分类、错误码与错误消息分离。

2.1 HTTP状态码类比:从传输层到业务层

HTTP状态码是业界最成熟的分层错误模型。将其设计哲学映射到业务错误码,可以快速建立团队共识:

HTTP 状态码范围 语义 业务错误码类比 典型场景
2xx (成功) 请求被正常处理 0 / 20000 系列 查询成功、操作完成
4xx (客户端错误) 请求参数或权限问题 40000 系列 参数校验失败、鉴权过期
5xx (服务端错误) 服务内部异常或依赖故障 50000 系列 数据库超时、下游服务不可用
设计建议:业务错误码不要直接复用 HTTP 状态码数字(如直接返回 400),而应使用独立编号体系。HTTP 状态码用于网关层,业务错误码用于应用层,两者互补而非替代。

2.2 业务错误码分类:三层结构

推荐采用 “模块 + 场景 + 具体错误” 的三层分类法,确保错误码具备可读性与可扩展性:

  • 模块标识(2位):如 01=用户模块、02=搜索模块、03=订单模块。
  • 场景标识(2位):如 01=参数校验、02=业务逻辑、03=依赖调用。
  • 具体错误(2位):从 01 递增,表示该场景下的具体错误原因。

示例:020301 表示“搜索模块 - 依赖调用 - 索引服务超时”。

分类清单(以搜索服务为例):
  • 20000 系列(成功):20000 = 成功,20001 = 部分命中。
  • 40000 系列(客户端错误):40001 = 查询参数为空,40002 = 排序字段不合法,40003 = 分页越界。
  • 50000 系列(服务端错误):50001 = 索引加载失败,50002 = 分词服务超时,50003 = 缓存穿透。
业务错误码三层分类结构 业务错误码三层分类结构 模块标识 (2位) 01=用户 02=搜索 03=订单 场景标识 (2位) 01=参数 02=逻辑 03=依赖 具体错误 (2位) 01~99 递增编号 示例:020301 → 搜索模块(02) + 依赖场景(03) + 超时(01) 总长度 6 位数字,支持按模块/场景快速过滤与告警聚合 优点:可读性强、支持正则匹配、便于自动化断言

2.3 错误码与错误消息分离

这是生产级系统最容易忽略的设计。错误码是机器标识,错误消息是人类描述,两者必须解耦:

  • 错误码:固定不变,用于日志聚合、告警规则、断言判断、发布回滚触发。
  • 错误消息:可随版本迭代优化文案、支持国际化,不影响已有监控逻辑。
常见反模式:将错误消息直接拼入错误码字段(如返回 {"code": "PARAM_ERROR: 用户名不能为空"})。这会导致监控系统无法聚合、断言无法匹配、回滚策略失效。

推荐返回结构(JSON):

{
  "code": 40001,
  "message": "查询参数为空",
  "detail": "搜索关键词长度不能少于2个字符",
  "trace_id": "a1b2c3d4e5f6"
}

其中 code 用于断言与回滚决策,message 用于前端展示,detail 用于开发排障,trace_id 用于链路追踪。

错误码与错误消息分离架构 错误码与错误消息分离架构 错误码 (code) 固定不变 用于断言/告警/回滚 错误消息 (message) 可随版本优化 支持国际化/多语言 解耦 互不影响独立演进 变更错误消息无需修改断言规则,发布回滚策略不受文案影响 最佳实践:错误码由 API 网关或基础库统一管理,错误消息由业务模块按需配置

2.4 错误码设计检查清单

检查项 通过标准 反例
唯一性 每个错误码全局唯一 不同模块共用 40001
可扩展 新增错误码不改变已有编号 重新编排整个序列
可读性 从编号可推断模块与场景 纯随机数字
消息分离 code 与 message 为独立字段 code 字段包含文案
断言友好 支持范围匹配(如 50000~59999) 仅支持精确匹配
本节要点:
  • 错误码设计应借鉴 HTTP 状态码的分层思想,但独立编号。
  • 推荐“模块 + 场景 + 具体错误”的三层结构,便于自动化处理。
  • 错误码与错误消息必须分离,这是发布回滚断言能够稳定工作的前提。