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)