github.com/nibnait/go-learn@v0.0.0-20220227013611-dfa47ea6d2da/chapter/ch9_性能调优.md (about) 1 ## 性能调优 2 3 [/src/main/tools](../src/main/chapter/ch8_02_http) 4 5 ### 准备⼯作 6 7 - 安装 graphviz 8 9 > brew install graphviz 10 11 - 将 $GOPATH/bin 加⼊ $PATH 12 13 > Mac OS: 在 .bash_profile 中修改路径 14 15 - 安装 go-torch 16 17 > go get -u github.com/uber/go-torch 18 > 19 > 下载并复制 flamegraph.pl (https://github.com/brendangregg/FlameGraph)⾄ $GOPATH/bin 路径下 20 > 21 > 将 $GOPATH/bin 加⼊ $PATH 22 23 ### 通过⽂件⽅式输出 Profile 24 25 - 灵活性⾼,适⽤于特定代码段的分析 26 - 通过⼿动调⽤ runtime/pprof 的 API 27 - API 相关⽂档 https://studygolang.com/static/pkgdoc/pkg/runtime_pprof.htm 28 - go tool pprof [binary] [binary.prof] 29 30 > go build prof.go 31 > 32 > ls 33 > 34 > ./prof 35 > 36 > ls 37 > 38 > go tool pprof prof cpu.prof 39 > 40 > > top 41 > > 42 > > list fillMatrix 43 > > 44 > > svg 45 > > 46 > > exit 47 > 48 > go-torch cpu.prof(查看火炬图) 49 > 50 > go tool pprof prof mem.prof 51 > 52 > // 先gc 在 dump,,再重新观察 53 > 54 > go tool pprof prof cpu.prof 55 > 56 > > list 57 58 59 60 ### 通过 http 方式输出 Profile 61 62 - 简单,适合于持续性运⾏的应⽤ 63 - 在应⽤程序中导⼊ import _ "net/http/pprof",并启动 http server 即可 64 - http://<host>:<port>/debug/pprof/ 65 - go tool pprof http://<host>:<port>/debug/pprof/profile?seconds=10 (默认值为30秒) 66 - go-torch -seconds 10 http://<host>:<port>/debug/pprof/profile 67 68 > go run fb_server.go 69 > 70 > http://127.0.0.1:8081/fb 71 72 73 74 > go build fb_server.go 75 > 76 > ./fb_server 77 > 78 > go tool pprof prof cpu.prof 79 > 80 > > top 81 > > 82 > > list fillMatrix 83 > > 84 > > svg 85 > 86 > go tool pprof prof cpu.prof 87 > 88 > > list 89 90 ## 性能调优示例 91 92 ### 常⻅分析指标 93 94 - Wall Time 95 - CPU Time 96 - Block Time 97 - Memory allocation 98 - GC times/time spent 99 100 > cd src/test/ch9 101 > 102 > go test -bench=. 103 > 104 > go test -bench=. -cpuprofile=cpu.prof 105 > 106 > go tool pprof cpu.prof 107 > 108 > > top -cum 109 > > 110 > > top 111 > > 112 > > list processRequest 113 > 114 > go test -bench=. -memprofile=mem.prof 115 > 116 > go tool pprof mem.prof 117 118 > go help testflag 119 120 ### 别让性能被“锁”住 121 122 - 减少锁的影响范围 123 - 减少发⽣锁冲突的概率 124 - sync.Map 125 - 适合读多写少,且 Key 相对稳定的环 境 126 - 采⽤了空间换时间的⽅案,并且采⽤指针的⽅式间接实现值的映射,所以存储空间会较 built-in map ⼤ 127 - **ConcurrentMap** 128 - 适⽤于读写都很频繁的情况 129 - 避免锁的使⽤ 130 - LAMX **Disruptor**:https://martinfowler.com/articles/lmax.html 131 132 ### GC 友好的代码 133 134 #### 避免内存分配和复制 135 136 - 复杂对象尽量传递引⽤ 137 - 数组的传递 138 - 结构体传递 139 - 初始化⾄合适的⼤⼩ 140 - ⾃动扩容是有代价的 141 - 复⽤内存 142 143 #### 打开 GC ⽇志 144 145 只要在程序执⾏之前加上环境变量 GODEBUG=gctrace=1, 146 147 > GODEBUG=gctrace=1 go test -bench=. 148 > 149 > GODEBUG=gctrace=1 go run main.go 150 151 ⽇志详细信息参考: https://godoc.org/runtime 152 153 > cd 03_gc_friendly 154 > 155 > go test -bench=BenchmarkPassingArrayWithRef -trace=trace_ref.out 156 > 157 > go test -bench=BenchmarkPassingArrayWithValue -trace=trace_val.out 158 > 159 > ls 160 > 161 > go tool trace trace_ref.out 162 > 163 > go tool trace trace_val.out 164 165 ## ⾼效的字符串连接 166 167 strings.Builder 168 169 ## 面向错误的设计 170 171 ### 隔离错误 - 设计 172 173 微内核 174 175 ### 隔离错误 - 部署 176 177 微服务 178 179 ### 重用 vs 隔离 180 181 逻辑结构的重用 + 部署结构的隔离 182 183 ### 冗余 184 185 主从 186 187 ### 限流 188 189 ### 慢响应 190 191 A quick rejection is better than a slow response. 192 193 给阻塞操作都加上⼀个期限(配置接口、服务 级别的超时时间) 194 195 ### 错误传递 196 197 断路器(服务降级) 198 199 ## 面向恢复的设计 200 201 ### 健康检查 202 203 - 注意僵⼫进程 204 - 池化资源耗尽 205 - 死锁 206 207 ### 构建可恢复的系统 208 209 - 拒绝单体系统 210 - ⾯向错误和恢复的设计 211 - 在依赖服务不可⽤时,可以继续存活 快速启动 212 - ⽆状态 213 214 ### 与客户端协商 215 216 相同请求,一段时间内 不要发送过来 217 218 # 相关开源项⽬ 219 220 [https://github.com/Netflix/chaosmonkey](https://github.com/Netflix/chaosmonkey) 221 222 [https://github.com/easierway/service_decorators/blob/master/README.md](https://github.com/easierway/service_decorators/blob/master/README.md)