docker load 与 docker pull

最近发现一种很奇葩的情况:

A机push镜像a(版本:0.0.0,hash值:a)到harbor

A机修改了a的容器并commit了镜像b(版本:0.0.0,hash值:b)

A机push镜像b上harbor

A机 save镜像a成tar包并通过USB直接传给B机

B机load tar包得到镜像a(版本号:0.0.0,hash值:a)

B机pull harbor上版本号为0.0.0的镜像

发现B机全部层重拉

B机pull harbor上hash为a的镜像,不用重拉

但是,dockerHub完全没有以上问题,区别就在于,dockerHub和harbor的存储结构不一样,harbor有一个镜像层标识,docker save会抹除这个标识,导致无法识别

githubFlow

1. githubflow有什么用

githubflow是指github的工作流(详细可看github的Action选项)

githubflow常用于:

  • merge时,自动检测是否有错误
  • merge时,自动打包镜像并部署(这个最厉害,自动化cicd)

1.语法

使用的是yaml语法

关键字 解释 示例
name 工作流名称
on 在什么时候触发工作流 看2.1
jobs 工作流具体内容 看2.2

示例

  • 2.1
1
2
3
on:
push: //当进行push时
branches:[ "master" ] //push到分支master时
  • 2.2
1
2
3
4
5
6
7
8
9
jobs:
build: //构建阶段
runs-on: ubuntu-latest //使用ubuntu-latest镜像

steps: //后续步骤
- uses: action/checkout@v3 //使用该action库,actions/checkout 是一个官方提供的 GitHub Action,用于检查出代码。@v3 指定了动作的版本,这里使用的是版本 3
- name: (该过程的名称,自定义)
run: | //|用于表示准备多行字符串
(这里写一下自己的构建镜像的shell命令)

Go pprof

https://github.com/hyper0x/go_command_tutorial/blob/master/0.12.md

是go应用于监测cpu异常飙升 内存泄露 等异常情况的工具

一般在/debug/pprof/路径下,使用get请求就能拿到文件了

命令行使用方法

  • 下载profile文件(好像还有别的文件,这个是示例,profile存有cpu的使用情况)
1
go tool pprof https://xxx/debug/pprof/profile
  • 下载好后会显示下载路径(例如)
1
Saved profile in /Users/pprof/pprof.http_server.samples.cpu.001.pb.gz
  • 下载好后会自动进入pprof的交互命令行
1
(pprof)
  • (pprof) help(看一下他的使用手册)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Commands:
callgrind Outputs a graph in callgrind format
comments Output all profile comments
disasm Output assembly listings annotated with samples
dot Outputs a graph in DOT format
eog Visualize graph through eog
evince Visualize graph through evince
gif Outputs a graph image in GIF format
gv Visualize graph through gv
kcachegrind Visualize report in KCachegrind
list Output annotated source for functions matching regexp
pdf Outputs a graph in PDF format
peek Output callers/callees of functions matching regexp
png Outputs a graph image in PNG format
proto Outputs the profile in compressed protobuf format
ps Outputs a graph in PS format
raw Outputs a text representation of the raw profile
svg Outputs a graph in SVG format
tags Outputs all tags in the profile
text Outputs top entries in text form
top Outputs top entries in text form
topproto Outputs top entries in compressed protobuf format
traces Outputs all profile samples in text form
tree Outputs a text rendering of call graph
web Visualize graph through web browser
weblist Display annotated source in a web browser
o/options List options and their current values
q/quit/exit/^D Exit pprof

Options:
call_tree Create a context-sensitive call tree
compact_labels Show minimal headers
divide_by Ratio to divide all samples before visualization
drop_negative Ignore negative differences
edgefraction Hide edges below <f>*total
focus Restricts to samples going through a node matching regexp
hide Skips nodes matching regexp
ignore Skips paths going through any nodes matching regexp
intel_syntax Show assembly in Intel syntax
mean Average sample value over first value (count)
nodecount Max number of nodes to show
nodefraction Hide nodes below <f>*total
noinlines Ignore inlines.
normalize Scales profile based on the base profile.
output Output filename for file-based outputs
prune_from Drops any functions below the matched frame.
relative_percentages Show percentages relative to focused subgraph
sample_index Sample value to report (0-based index or name)
show Only show nodes matching regexp
show_from Drops functions above the highest matched frame.
source_path Search path for source files
tagfocus Restricts to samples with tags in range or matched by regexp
taghide Skip tags matching this regexp
tagignore Discard samples with tags in range or matched by regexp
tagleaf Adds pseudo stack frames for labels key/value pairs at the callstack leaf.
tagroot Adds pseudo stack frames for labels key/value pairs at the callstack root.
tagshow Only consider tags matching this regexp
trim Honor nodefraction/edgefraction/nodecount defaults
trim_path Path to trim from source paths before search
unit Measurement units to display

Option groups (only set one per group):
granularity
functions Aggregate at the function level.
filefunctions Aggregate at the function level.
files Aggregate at the file level.
lines Aggregate at the source code line level.
addresses Aggregate at the address level.
sort
cum Sort entries based on cumulative weight
flat Sort entries based on own weight
: Clear focus/ignore/hide/tagfocus/tagignore

type "help <cmd|option>" for more information
  • (pprof)top(可以看到资源消耗的top10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Showing nodes accounting for 2950ms, 49.58% of 5950ms total
Dropped 454 nodes (cum <= 29.75ms)
Showing top 10 nodes out of 455
flat flat% sum% cum cum%
1660ms 27.90% 27.90% 1660ms 27.90% runtime/internal/syscall.Syscall6
580ms 9.75% 37.65% 580ms 9.75% runtime.futex
150ms 2.52% 40.17% 150ms 2.52% runtime.nextFreeFast (inline)
100ms 1.68% 41.85% 100ms 1.68% runtime.memclrNoHeapPointers
90ms 1.51% 43.36% 480ms 8.07% runtime.mallocgc
80ms 1.34% 44.71% 90ms 1.51% runtime.findObject
80ms 1.34% 46.05% 80ms 1.34% runtime.mapaccess1
80ms 1.34% 47.39% 270ms 4.54% runtime.scanobject
70ms 1.18% 48.57% 70ms 1.18% runtime.memmove
60ms 1.01% 49.58% 60ms 1.01% runtime.(*itabTableType).find

图形化显示

1
2
先下载一下这个东西
https://graphviz.org/download/
  • 启动web图形化界面
1
go tool pprof -http=:8000 /Users/pprof/pprof.http_server.samples.cpu.001.pb.gz

Cherry-pick

goland中打开git分支图,右键任意一个commit就可以看到

用处

把其他分支(分支A)的某一个commit copy到另一个分支(分支B)

分支B不会继承分支A其他commit

应用场景

非常适合小白不小心写到master,不能push,又不想删除代码,开了个新分支,想把刚写的代码copy过来

go通过channel控制并发任务

1. 通过context来控制全体退出

在主协程中创建一个父context,之后的子协程都使用父context生成子context并传递过去

  • context.WithCancelCause(contextFather)

生成子context

  • context.Done()

是一个channel,如果该context或者是父级的context执行了cancel(也可以理解为死掉了),那就会在这个channel中接收到东西,然后可以用于判断context是否退出了

  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//获得子context
func main() {
contextChild, _ := context.WithCancelCause(contextFather)
go heart(contextChild, cancelFather)
go func1(contextChild, cancelFather)
select {
//阻塞等待任务都完成
case <-contextFather.Done():
time.Sleep(3 * time.Second)
return
}
}

//最好有个心跳任务,断连就触发cancel
func heart(ctx context.Context, cancel context.CancelCauseFunc) {
for {
select {
//心跳任务发现用户断开,主动cancel 或者 任务出现error,主动cancel
case <-ctx.Done():
return
default:
(具体心跳逻辑)
}
}
}

func func1(ctx context.Context, cancel context.CancelCauseFunc) {
for {
select {
//心跳任务发现用户断开,主动cancel 或者 任务出现error,主动cancel
case <-ctx.Done():
return
default:
(具体任务内容)
}
}
}

2. 通过channel并发输出resp

  • 通过参数传递同一个channel变量,实现多协程使用同一channel
  • 进阶上面的context控制并发,再创一个输出resp任务
1
2
3
4
5
6
7
8
9
10
11
func writeMessage(ctx context.Context, cancel context.CancelCauseFunc, resp chan []byte) {
for {
select {
//心跳任务发现用户断开,主动cancel 或者 任务出现error,主动cancel
case <-ctx.Done():
return
case data := <-resp:
(具体输出逻辑)
}
}
}