高质量编码与性能调优 | 青训营笔记

119 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天.

高质量编码与性能调优

  • 正确可靠,简洁清晰
  • 各种边界问题是否考虑完备
  • 异常情况处理,稳定性保证
  • 易读易维护

编程原则

  • 简单性:逻辑简单清晰
  • 可读性:可维护
  • 生产力:团队合作

编码规范

代码格式

  • 格式化工具 gofmt,goimports

注释

  • 解释代码作用
  • 如何做的
  • 实现的原因
  • 什么情况会出错

命名规范

  • 简洁胜于冗长

变量

  • 缩略词全大写,但当期位于变量开头且不需要导出时,使用全小写。例:ServerHTTP,xmlHTTPRequest。
  • 变量距离其被使用的地方越远,需要越多的上下文信息。

函数

  • 函数名不携带包名,尽量简短

  • 只有小写字母组成,不包含大写和下划线等字符。
  • 简短并包含一定上下文信息,不要与标准库同名。

控制流程

  • 线性原理,避免嵌套,保证正常流程清晰,
  • 正常流程代码沿着屏幕向下移动,
  • 易读易维护。

错误和异常处理

简单错误

  • 仅出现一次的错误,优先使用error.New来创建匿名变量来直接表示错误,如果有格式化的需求,使用fmt.Errorf

错误的WrapUnwrap

  • wrap实际上提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链
  • fmt.Errorf中使用%w关键字将错误关联至错误链中

错误判定

  • 判断一个错误是否为特定错误,使用errors.ls
  • 不同于使用==,该方法可以判定错误链上的所有错误是否含有特定的错误。
  • 在错误链上获取特定种类的错误使用error.As

panic

  • 不建议在业务代码中使用panic
  • 调用函数不包含recover会造成程序崩溃
  • 若问题可以被屏蔽或解决,建议使用error代替panic
  • 当程序启动阶段发生不可逆转的错误时,可以在init或者main函数中使用panic

recover

  • recover只能被defer的函数中使用
  • 嵌套无法生效
  • 只在当前goroutine生效
  • defer的语句是后进先出
  • 如果需要更多的上下文信息,可以在recover后再log中记录当前的调用栈

性能优化建议

benchmark

slice 预分配内存

  • 尽可能在使用make()初始化切片时提供容量信息。
  • 可使用copy替代re-slice防止大内存未释放。

map 预分配内存

字符串处理

  • string.Builder处理字符串拼接,代替+,byte.Buffer

空结构体struct{}

  • 空结构体本身具有很强的语义,即这里不需要任何值,不占据任何的内存空间,可作为各种场景下的占位符使用,节省内存。
  • 可实现set

atomic包

  • 并发时替换加锁操作

性能调优原则

  • 依靠数据不是猜测
  • 定位最大瓶颈而不是细枝末节
  • 不要过早,过度优化

性能分析工具pprof

性能调优案例

业务服务优化

基本概念

  • 服务:能单独部署,承载一定功能的程序
  • 依赖:Service A 的功能实现依赖Service B的相应结果,称为Service A依赖Service B
  • 调用链路:能支持一个接口请求的相关服务集合及其相互之间的依赖关系
  • 基础库:公共的工具包、中间件

流程

  • 建立服务性能评估手段
  • 分析性能数据,定位性能瓶颈
  • 重点优化改造
  • 优化效果验证

建立服务性能评估手段

  • 服务性能评估方式

    • 单独 benchmark 无法满足复杂逻辑分析

    • 不同负载情况下性能表现差异

  • 请求流量构造

    • 不同请求参数覆盖逻辑不同

    • 线上真实流量情况

  • 压测范围

    • 单机器压测
    • 集群压测
  • 性能数据采集

    • 单机性能数据
    • 集群性能数据

分析性能数据,定位性能瓶颈

  • 使用库不规范
  • 高并发场景优化不足

重点优化改造

  • 正确性是基础
  • 响应数据 diff
    • 线上请求数据录制回放
    • 新旧逻辑接口数据 diff

优化效果验证

  • 重复压测验证
  • 上线评估优化效果
    • 关注服务监控
    • 逐步放量
    • 收集性能数据

进一步优化,服务整体链路分析

  • 规范上游服务调用接口,明确场景需求
  • 分析链路,通过业务流程优化提升服务性能