Skip to content

Commit

Permalink
docs(workspace): 多 Module 问题解决
Browse files Browse the repository at this point in the history
  • Loading branch information
Danny5487401 committed Dec 10, 2024
1 parent be208a0 commit 892d9ca
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 71 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ Note: 目录同级为 *代码展示*,推荐在 Goland 版本 2022.2.1+ 运行,
## [第二十八章 如何进行测试](chapter28_test/test.md)
- [1 testing](chapter28_test/01_testing/testing.md)
- 1.1 sub 测试并发
- 1.2 testing.M 将测试交给TestMain调度
- [1.2 testing.M 将测试交给TestMain调度](chapter28_test/01_testing/02_m/m_test.go)
- 1.3 testing.F 模糊测试
- [2 go-mock接口测试](chapter28_test/02_gomock/gomock.md)
- 3 web 测试
Expand All @@ -575,9 +575,10 @@ Note: 目录同级为 *代码展示*,推荐在 Goland 版本 2022.2.1+ 运行,
- [1 go-module 实践篇](chapter29_module/01_use/module_operation.md)
- 模块缓存
- GOPROXY
- [2 go-module原理篇](chapter29_module/02_discipline/module.md)
- [2 go-module 原理篇](chapter29_module/02_discipline/module.md)
- Minimal Version Selection 最小版本选择算法
- [3 go1.17 module依赖图修剪及延迟 module 加载](chapter29_module/03_go1.17_module/module.md)
- [3 go1.17 module 依赖图修剪及延迟 module 加载](chapter29_module/03_go1_17_module/module.md)
- [3 go1.18 workspace 工作区模式-->k8s 使用](chapter29_module/04_go1_18_workspace/workspace.md)


## 第三十章 内存管理
Expand Down
Binary file not shown.
12 changes: 7 additions & 5 deletions chapter02_goroutine/02_runtime/04_pprof/02_pkg_profile/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ func main() {
}

/*
# 第 1 行将 cpu.go 编译为可执行文件 cpu。
$ go build -o cpu cpu.go
# 第 2 行运行可执行文件,在当前目录输出 cpu.pprof 文件。
$ ./cpu
# 第 3 行,使用 go tool 工具链输入 cpu.pprof 和 cpu 可执行文件,生成 PDF 格式的输出文件,将输出文件重定向为 cpu.pdf 文件。
这个过程中会调用 Graphviz 工具,Windows 下需将 Graphviz 的可执行目录添加到环境变量 PATH
$ go tool pprof --pdf cpu cpu.pprof > cpu.pdf
代码说明如下:
第 1 行将 cpu.go 编译为可执行文件 cpu。
第 2 行运行可执行文件,在当前目录输出 cpu.pprof 文件。
第 3 行,使用 go tool 工具链输入 cpu.pprof 和 cpu 可执行文件,生成 PDF 格式的输出文件,将输出文件重定向为 cpu.pdf 文件。
这个过程中会调用 Graphviz 工具,Windows 下需将 Graphviz 的可执行目录添加到环境变量 PATH
*/
110 changes: 75 additions & 35 deletions chapter02_goroutine/02_runtime/04_pprof/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

- [Go 中监控代码性能pprof](#go-%E4%B8%AD%E7%9B%91%E6%8E%A7%E4%BB%A3%E7%A0%81%E6%80%A7%E8%83%BDpprof)
- [展示参数](#%E5%B1%95%E7%A4%BA%E5%8F%82%E6%95%B0)
- [源码](#%E6%BA%90%E7%A0%81)
- [两个包:](#%E4%B8%A4%E4%B8%AA%E5%8C%85)
- [内置库:两个包](#%E5%86%85%E7%BD%AE%E5%BA%93%E4%B8%A4%E4%B8%AA%E5%8C%85)
- [第三方性能分析包](#%E7%AC%AC%E4%B8%89%E6%96%B9%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%8C%85)
- [net/http/pprof 源码分析](#nethttppprof-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90)
- [Profile 举例](#profile-%E4%B8%BE%E4%BE%8B)
- [介绍](#%E4%BB%8B%E7%BB%8D)
- [介绍](#%E4%BB%8B%E7%BB%8D)
- [pprof 文件分析](#pprof-%E6%96%87%E4%BB%B6%E5%88%86%E6%9E%90)
- [第三方性能分析来分析代码包](#%E7%AC%AC%E4%B8%89%E6%96%B9%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E6%9D%A5%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E5%8C%85)
- [Go test 使用pprof](#go-test-%E4%BD%BF%E7%94%A8pprof)
- [参考](#%E5%8F%82%E8%80%83)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand All @@ -25,6 +26,20 @@ profile.proto 是一个 Protocol Buffer v3 的描述文件,它描述了一组

## 展示参数
![](.intro_images/pprof_args.png)
```go
// go1.23.0/src/net/http/pprof/pprof.go
var profileDescriptions = map[string]string{
"allocs": "A sampling of all past memory allocations",
"block": "Stack traces that led to blocking on synchronization primitives",
"cmdline": "The command line invocation of the current program",
"goroutine": "Stack traces of all current goroutines. Use debug=2 as a query parameter to export in the same format as an unrecovered panic.",
"heap": "A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.",
"mutex": "Stack traces of holders of contended mutexes",
"profile": "CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.",
"threadcreate": "Stack traces that led to the creation of new OS threads",
"trace": "A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.",
}
```

allocs 和 heap 采样的信息一致,不过前者是所有对象的内存分配,而 heap 则是活跃对象的内存分配

Expand All @@ -35,22 +50,35 @@ allocs 和 heap 采样的信息一致,不过前者是所有对象的内存分
- CPU profiling(CPU 性能分析):这是最常使用的一种类型。用于分析函数或方法的执行耗时;
- Memory profiling:这种类型也常使用。用于分析程序的内存占用情况;
- Block profiling:这是 Go 独有的,用于记录 goroutine 在等待共享资源花费的时间;
- Goroutine Profiling: 报告goroutines的使用情况,有哪些 goroutines,它们的调用关系是怎样的。
- Mutex profiling:与 Block profiling 类似,但是只记录因为锁竞争导致的等待或延迟。

### 源码
```go
profiles.m = map[string]*Profile{
"goroutine": goroutineProfile, //显示当前所有协程的堆栈信息
"threadcreate": threadcreateProfile, // 系统线程创建情况的采样信息
"heap": heapProfile, // 堆上的内存分配情况的采样信息
"allocs": allocsProfile, //内存分配情况的采样信息
"block": blockProfile, //阻塞操作情况的采样信息
"mutex": mutexProfile, // 锁竞争情况的采样信息
// go1.23.0/src/runtime/pprof/pprof.go
func lockProfiles() {
profiles.mu.Lock()
if profiles.m == nil {
// Initial built-in profiles.
profiles.m = map[string]*Profile{
"goroutine": goroutineProfile, //显示当前所有协程的堆栈信息
"threadcreate": threadcreateProfile, // 系统线程创建情况的采样信息
"heap": heapProfile, // 堆上的内存分配情况的采样信息
"allocs": allocsProfile, //内存分配情况的采样信息
"block": blockProfile, //阻塞操作情况的采样信息
"mutex": mutexProfile, // 锁竞争情况的采样信息
}
}
}

```

默认情况下是不追踪block和mutex的信息的,如果想要看这两个信息,需要在代码中加上两行
```go
runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪,block
runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪,mutex
```


## 两个包
## 内置库:两个包
1. net/http/pprof
使用场景:在线服务(一直运行着的程序)

Expand All @@ -59,6 +87,24 @@ profiles.m = map[string]*Profile{

这两个包都是可以监控代码性能的, 只不过net/http/pprof是通过http端口方式暴露出来的,内部封装的仍然是runtime/pprof。

## 第三方性能分析包
runtime.pprof 提供基础的运行时分析的驱动,但是这套接口使用起来还不是太方便,例如:
1. 输出数据使用 io.Writer 接口,虽然扩展性很强,但是对于实际使用不够方便,不支持写入文件。
2. 默认配置项较为复杂。

runtime/pprof使用起来有些不便,因为要重复编写打开文件,开启分析,结束分析的代码.

使用下面代码安装这个包
```go
go get github.com/pkg/profile
```
使用
```go
defer profile.Start().Stop()
```



## net/http/pprof 源码分析
```go
// net/http/pprof/pprof.go
Expand All @@ -79,7 +125,7 @@ func init() {

直接使用如下命令,则不需要通过点击浏览器上的链接就能进入命令行交互模式:
```go
go tool pprof http://47.93.238.9:8080/debug/pprof/profile
go tool pprof http://x.x.x.x:8080/debug/pprof/profile

```

Expand All @@ -89,21 +135,21 @@ go tool pprof http://47.93.238.9:8080/debug/pprof/profile
类似的命令还有:
```shell
# 下载 cpu profile,默认从当前开始收集 30s 的 cpu 使用情况,需要等待 30s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile
go tool pprof http://127.0.0.1:8080/debug/pprof/profile
# wait 120s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile?seconds=120
go tool pprof http://127.0.0.1:8080/debug/pprof/profile?seconds=120

# 下载 heap profile
go tool pprof http://47.93.238.9:8080/debug/pprof/heap
go tool pprof http://127.0.0.1:8080/debug/pprof/heap

# 下载 goroutine profile
go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine
go tool pprof http://127.0.0.1:8080/debug/pprof/goroutine

# 下载 block profile
go tool pprof http://47.93.238.9:8080/debug/pprof/block
go tool pprof http://127.0.0.1:8080/debug/pprof/block

# 下载 mutex profile
go tool pprof http://47.93.238.9:8080/debug/pprof/mutex
go tool pprof http://127.0.0.1:8080/debug/pprof/mutex
```

### Profile 举例
Expand All @@ -124,12 +170,15 @@ func Profile(w http.ResponseWriter, r *http.Request) {

StartCPUProfile()方法传入的是http.ResponseWriter类型变量,所以采样结果直接写回到 HTTP 的客户端

## 介绍
## 介绍
runtime/pprof中的程序来生成三种包含实时性数据的概要文件,分别是

1. CPU概要文件
在默认情况下,Go语言的运行时系统会以100 Hz的的频率对CPU使用情况进行取样。

2. 内存概要文件
内存概要文件用于保存在用户程序执行期间的内存使用情况。这里所说的内存使用情况,其实就是程序运行过程中堆内存的分配情况。

3. 程序阻塞概要文件
程序阻塞概要文件用于保存用户程序中的Goroutine阻塞事件的记录。

Expand All @@ -139,25 +188,16 @@ runtime/pprof中的程序来生成三种包含实时性数据的概要文件,
pprof 文件是二进制的,不是给人读的,需要翻译一下,而 golang 原生就给我们提供了分析工具,直接执行下面命令即可,会生成一张很直观的 svg 图片,
直接用 chrome 就可以打开,当然也可以生成别的格式(pdf,png 都可以),可以用 go tool pprof -h 命令查看支持的输出类型

## 第三方性能分析来分析代码包
runtime.pprof 提供基础的运行时分析的驱动,但是这套接口使用起来还不是太方便,例如:
1. 输出数据使用 io.Writer 接口,虽然扩展性很强,但是对于实际使用不够方便,不支持写入文件。
2. 默认配置项较为复杂。

runtime/pprof使用起来有些不便,因为要重复编写打开文件,开启分析,结束分析的代码.

使用下面代码安装这个包
```go
go get github.com/pkg/profile
```
使用
```go
defer profile.Start().Stop()
```
## Go test 使用pprof

Golang在运行测试用例或压测时也可以通过添加参加输出测试过程中的CPU、内存和trace情况


## 参考

- [万字长文讲解Golang pprof 的使用](https://juejin.cn/post/7343428554686611495)



Expand Down
4 changes: 2 additions & 2 deletions chapter28_test/01_testing/03_f/sum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func FuzzSum(f *testing.F) {
}

func FuzzReverse(f *testing.F) {
str_slice := []string{"abc", "bb"}
for _, v := range str_slice {
strSlice := []string{"abc", "bb"}
for _, v := range strSlice {
f.Add(v)
}
f.Fuzz(func(t *testing.T, str string) {
Expand Down
6 changes: 3 additions & 3 deletions chapter28_test/01_testing/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- [testing](#testing)
- [内置 testing 库中的包类型](#%E5%86%85%E7%BD%AE-testing-%E5%BA%93%E4%B8%AD%E7%9A%84%E5%8C%85%E7%B1%BB%E5%9E%8B)
- [公共类 testing.commmon](#%E5%85%AC%E5%85%B1%E7%B1%BB-testingcommmon)
- [公共类 testing.common](#%E5%85%AC%E5%85%B1%E7%B1%BB-testingcommon)
- [T 平常使用的单元测试](#t-%E5%B9%B3%E5%B8%B8%E4%BD%BF%E7%94%A8%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95)
- [B 基准测试](#b-%E5%9F%BA%E5%87%86%E6%B5%8B%E8%AF%95)
- [M 可预置测试前后的操作](#m-%E5%8F%AF%E9%A2%84%E7%BD%AE%E6%B5%8B%E8%AF%95%E5%89%8D%E5%90%8E%E7%9A%84%E6%93%8D%E4%BD%9C)
Expand All @@ -28,7 +28,7 @@
- testing.PB: 测试时并行执行.


### 公共类 testing.commmon
### 公共类 testing.common


testing.T和testing.B 属于testing.common的扩展。
Expand Down Expand Up @@ -200,4 +200,4 @@ type F struct {
## 参考


- 源码 Jay Conrod 博客:https://jayconrod.com/posts/123/internals-of-go-s-new-fuzzing-system
- [Jay Conrod 关于 Internals of Go's new fuzzing system](https://jayconrod.com/posts/123/internals-of-go-s-new-fuzzing-system)
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [Go 1.17 新特性: module依赖图修剪与延迟module加载](#go-117-%E6%96%B0%E7%89%B9%E6%80%A7-module%E4%BE%9D%E8%B5%96%E5%9B%BE%E4%BF%AE%E5%89%AA%E4%B8%8E%E5%BB%B6%E8%BF%9Fmodule%E5%8A%A0%E8%BD%BD)
- [Go 1.17 新特性: module依赖图修剪(module graph pruning)与延迟module加载(lazy module loading)](#go-117-%E6%96%B0%E7%89%B9%E6%80%A7-module%E4%BE%9D%E8%B5%96%E5%9B%BE%E4%BF%AE%E5%89%AAmodule-graph-pruning%E4%B8%8E%E5%BB%B6%E8%BF%9Fmodule%E5%8A%A0%E8%BD%BDlazy-module-loading)
- [module依赖图修剪 module graph pruning](#module%E4%BE%9D%E8%B5%96%E5%9B%BE%E4%BF%AE%E5%89%AA-module-graph-pruning)
- [延迟module加载(lazy module loading)](#%E5%BB%B6%E8%BF%9Fmodule%E5%8A%A0%E8%BD%BDlazy-module-loading)
- [module deprecation注释](#module-deprecation%E6%B3%A8%E9%87%8A)
- [参考](#%E5%8F%82%E8%80%83)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# Go 1.17 新特性: module依赖图修剪与延迟module加载
# Go 1.17 新特性: module依赖图修剪(module graph pruning)与延迟module加载(lazy module loading)

module依赖图修剪(module graph pruning)是延迟module加载(lazy module loading)的基础。

## module依赖图修剪 module graph pruning

Expand Down Expand Up @@ -74,6 +77,9 @@ require (



但module依赖图修剪也带来了一个副作用,那就是go.mod文件size的变大。因为Go 1.17版本后,每次go mod tidy,go命令都会对main module的依赖做一次深度扫描(deepening scan),并将main module的所有直接和间接依赖都记录在go.mod中。

考虑到内容较多,go 1.17将直接依赖和间接依赖分别放在两个不同的require块儿中。
## 延迟module加载(lazy module loading)


Expand All @@ -91,4 +97,9 @@ go module作者只需在自己的go.mod中的module声明上面用**// Deprecate
module example.com/mod
```

对于那些使用了被废弃的module的go项目,go list、go get命令都会给出warning。
对于那些使用了被废弃的module的go项目,go list、go get命令都会给出warning。


## 参考

- [Go 1.17新特性详解:module依赖图修剪与延迟module加载](https://tonybai.com/2021/08/19/go-module-changes-in-go-1-17/)
Loading

0 comments on commit 892d9ca

Please sign in to comment.