这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
讲师和内容介绍
- 介绍编码规范,帮助大家写出高质量程序
- 介绍 Go 语言的性能优化建议,分析对比不同方式对性能的影响和背后的原理
- 讲解常用性能分析工具 pprof 的使用和工作原理,熟悉排查程序性能问题的基本流程
- 分析性能调优实际案例,介绍实际性能调优时的工作内容
课程目录
高质量编程
注意边界和异常情况
编码规范
代码格式使用gofmt自动化格式
不需要注释接口方法
表达上下文信息?有点类似写论文?
命名:简洁胜于冗长,缩略词大写,开头不需要导出要小写
全局变量的名字多带上下文信息,了解变量的含义
函数名尽量简短,注意返回类型相同否
1更好,应为包相同可以省略,用的时候是http.Serve
都有return,避免分支嵌套
对于异常情况,正常返回
只出现一次错误,直接errors.NeW
错误链是否有指定的错误
一般不用panic,示例代码启动一个消费队列的消费组,启动失败会用log.panicf方法,最后就会打印错误日志,发送panic(需要尽早暴露问题)
其他库碰到panic怎么做,影响自身逻辑的时候,需要用recover以,
关键字panic的作用是制造一次宕机,宕机就代表程序运行终止,但是已经“生效”的延迟函数仍会执行(即已经压入栈的defer延迟函数,panic之前的),golang中的recover也只是发生宕机之后的后事处理
recover的操作在于出现panic的上下文记录,主要就是打印调用栈记录下来,能够知道什么原因导致的
从左往右,1 2
3 1
性能优化
go test -bench=. -benchmem
8 是设置的核数
有无预分配消息,如果提前分配会有好的效果
创建一个新的数组,用copy和直接retrun的区别
go test -run=. -v
map有点同理
字符串是高频操作
直接用+会变差,原因会开辟新空间
知道最后长度的时候,可以进一步提高效率,用grow的方法直接把大小计算好
可以看最后一列内存分配的次数
使用set的情况下,只要键,不用值
多线程计数器,atimic维护变量,可以看出用atomic的时间性能比较好
性能调优实战
性能分析工具pprof
go mod tidy
go mod init github.com/wolfogre/go-pprof-practice
main方法流程:把pprof注册到httpserver,设置了cpu数,开启了锁和阻塞的调用跟踪,实际启动时6060
访问http://127.0.0.1:6060/debug/pprof/
根据参考分析哪些点存在性能问题
点full 会是平铺的
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
采集十秒的数据来辅助性能问题
使用了top指令的内容
cum是调用其他函数的总耗时,没有调用的时候flat ==cum,flat都是调用别人的时候 flat == 0
list eat
web命令可视化
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/cpu"
如果把重要的东西注释即可
如果i想要可视化,在指令里加 -http=:8080即可
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
可以发现mouse是占用最多,view是有很多,展示图要有graphviz
source视图类似list命令到的视图,代码注释后会发现内存下降
可以看到不同占用内存大小的问题
goroutine 协程的问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
关心的协程的性能的问题可以知道有东西创造了很多协程
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
看到了block的的问题
回到命令行问题,有没有特殊的问题,丢弃了四个节点,用了简单过滤条件,可以展示出来
找到了阻塞操作
main里有个block,rate
需要优化的案例
紫色的点可以定位,可以看到每次拿到之后就要解析,这里面没用到缓存机制,只要修改变动的时候再去修改即可
规范日志
对于高峰和低峰进行采样,专门优化即可,监控上报不需要实时,直接异步上报即可
对于功能方面需要进行修改,对比实例,需要对字段进行改动
单独一点的优化转变到链路的优化
通过火焰图来判断,百分比来改善
Q&A
1:关于编码规范,本包调用的时候?
和之前可以一样,没有必要修改,你知道自己写的方法了
2:抖音项目地址是否支持https地址
可以直接配置域名和服务地址,后面具体更新在文档里
3:go的设计模式?
设计模式为了写出更好的代码,go本身自己的实践经验参考一些手册,和java区别很大
4:设计项目的过程是否支持自定义?
项目的话是服务端的青训营,自定义功能对于客户端也得有调整,就没有办法统一评估了,暂时不会开发客户端修改的调整,专注于服务端的性能,和用户使用场景
5:线上应用panic排除,除了打标还有什么方式?
用到panic的话,会有日志能够定位问题,panic调用堆栈,可以查看代码逻辑,对于nil的情况是不是传入参数导致后续调用panic了,进而一步一步定义问题
go本身自带debug工具对于线上服务不太好开放,怕对服务产生影响
如果产生很难的问题,会拿出实例单独对go本身的debug方式,打断点来看内存分配和堆栈
6:压力测试怎么做的?
好的压测平台公司是有单独团队,对于个人需要了解一下上述提到的工具,实现自己功能的时候可以对自己小块的逻辑是怎么样的?也有一些开源的压力测试工具产生报告?先对这些压力测试碰到的问题进行了解,后续真的需要用到的话会更熟悉一些
7:接口规范?
实际关于其他类型,可以观看手册里的相关类型的文档。