第 2 章 规范

《代码精进之路 从码农到工匠》学习笔记目录

原书:《代码精进之路 从码农到工匠》 | 作者:张建飞

有序可以降低复杂度

同样的数字,排列不同,复杂度也不同

无序

  • 3495812067
  • 58743594183007622169

有序

  • 1234567890
  • 11223344556677889900

2.3.4 日志规范

ERROR 级别

  • 表示不能自己恢复的错误,需要立即被关注和解决
  • 例如:数据库操作错误、I/O 错误、未知的错误
  • 建议:
    • 打印相关上下文(链路追踪 Id、用户 Id、订单 Id 等重要信息)便于快速定位问题
    • 接入监控和报警系统,及时止损。但不要滥用,否则就会出现“狼来了”,😅😅😅😓😓😓

WARN 级别

  • 可预知的业务问题
  • 例如:参数校验不通过、没有访问权限等业务异常
  • 注意:段时间内产生过多的 WARN 日志,也是系统不健康的表现
  • 建议:为 WANR 配置一个适当报警阈值,比如访问受限 WARN 超过 100 次/分钟,则发出报警

INFO 级别

  • 记录系统的基本运行过程和运行状态
  • 适当的 INFO 日志可以协助我们排查问题,同样不要滥用

DEBUG 级别

  • 输出调试信息
  • 如 request/response 的对象内容
  • 通常在开放和预发环境下,DEBUG 日志会打开,方便调试
  • 生产环境,DEBUG 一般是关闭状态,避免因日志过大而拖垮业务系统
  • 防止日志过大的几种方案:
    • 采用 TDD 开发,以功能测试代替 低效的 DEBUG
    • Alibaba 开源的 Java 诊断工具 Arthas
    • 通过开关控制想要打印的日志,例如基于 requestId 判断的日志过滤

2.3.5 异常规范

糟糕的异常

  • 到处充斥着 try/catch 的代码,扰乱了代码结构:错误处理与正常流程混在一起,严重影响代码可读性
  • 异常处理不统一:有的直接抛出异常,有的对外反回错误码。这让服务的调用方摸不着头脑,增加了使用与沟通成本

建议设定两种异常:BizException(业务异常) 和 SysException(系统异常)

这两种异常都应该是 Unchecked Exception

因为用 Checked Exception 就破坏了开闭原则

针对 BizException(业务异常) 和 SysException(系统异常) 做统一的异常处理

假设使用 AOP 处理所有异常

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
try {
    // 业务处理
}
catch (BizException e) {
    log.warn("业务异常")
}
catch (SysException e) {
    log.error("系统异常")
}
catch (Exception e) {
    log.error("兜底")
}

千万不要在业务处理内部到处使用 try/catch 打印错误日志,这样会使功能代码和业务代码纠缠在一起,让代码看起来很凌乱,影响代码可读性

错误码

编号错误码

  • 对于平台、底层系统或软件产品,可以采用
  • 优点:编码风格固定,看起来专业
  • 缺点:需要配合文档才能理解错误码的含义
  • 注意:对不同的错误波段,要预留足够的号码
    • 淘宝开放平台使用 3 位数,超过 100 后,为了向后兼容,只能通过子错误码的方式变通处理

显性化错误码

  • 优点:具有更强的灵活性,适合敏捷开发
  • 例如:将错误码定义为 3 个部分 类型 + 场景 + 自定义标识

约定示例

  • P_Customer_NameIsNotNull 客户姓名不能为空
  • B 代表业务异常(Biz Excepion)
  • S 代表系统异常(System Exception)
错误类型错误码约定举例
参数异常P_XX_XXP_Customer_NameIsNotNull 客户姓名不能为空
业务异常B_XX_XXB_Customer_NameAlreadyExist 客户姓名已存在
系统异常S_XX_XXS_Unkonw_Error 未知系统错误
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus