高质量
- 边界条件处理完备
- 异常情况稳定处理
- 易读,易维护
编码规范
- 代码格式
- 使用IDE集成的工具,细节由团队商议
- 注释
- 除去常规的一些解释说明,特定场景下注释需要包含一部分业务场景来说明该段代码加入的原因
- 公共符号始终要注释
- 命名规范
- 简洁胜过冗长
- 变量距离被使用的地方越远,需要携带的上下文信息就越多
- 核心目标是降低阅读代码的成本,重点考虑上下文信息,设计简介清晰的命名
- 控制流
- 处理逻辑尽量走直线,主干为正常流程
- 错误和异常处理
- error尽量简明上下文信息链,方便定位
- pancic(直接cursh)用于真正异常
性能调优
- 必须参考实际数据衡量
- 使用benchmark工具进行性能测试
- 避免常见的性能陷阱
- 内存预分配
- 普通应用代码不用过于追求性能
- 越高级的优化手段越容易出问题
- 满足正确可靠、简明的前提下,进行性能优化
原则
- 靠数据而非猜测
- 定位最大瓶颈而非细枝末节
- 不过早优化,防止后期业务逻辑修改
- 不过度优化,过度优化的往往耦合性强,更难扩展
go性能分析工具pprof原理简介
- CPU
- 调用函数及他们占用的时间
- os每隔10ms向进程发送一个信号,进程接收到信号记录调用堆栈,每隔100ms将记录写入输出流
- Heap-堆内存
- 采样程序通过内存分配器在heap上的分配和释放,记录分配/释放的大小和数量
- Goroutine-协程
- 记录所有用户发起且在运行中的goroutine
- ThreadCreate
- 记录程序创建所有系统线程的信息
- 阻塞
- 采样阻塞操作次数和耗时,超过阈值才会被记录
- 锁
- 锁竞争,采样争抢锁的次数和耗时
实践
流程
- 建立服务性能评估手段
- 评估方式
- 流量构造(复杂)
- 压测范围
- 性能数据采集
- 分析性能数据,定位瓶颈
- 函数/库使用不规范
- 高并发场景优化不足
- 重点优化项改造
- 正确是基础
- 效果验证
- 重复验证效果
- 上线评估优化效果
- 逐步放流
- 收集性能数据 进一步优化
- 分析服务整体链路
- 规范上游服务调用接口,明确场景需求
- 分析链路,通过业务流程优化提升服务性能
- 基础库优化
- AB实验SDK优化
- 编译器&运行时优化
总体来说,性能调优
- 先保证正确性,再进行调优
- 定位主要瓶颈,放弃细枝末节
- 确定业务场景的真实需求,再进行优化
- 除去简单优化,尽量先关注扩展性,后关注优化
- 不宜过度优化