成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

學會這幾招讓 Go 程序自己監控自己

開發 后端
談到讓Go程序監控自己進程的資源使用情況,那么就讓我們先來談一談有哪些指標是需要監控的,一般談論進程的指標最常見的就是進程的內存占用率、CPU占用率、創建的線程數。因為Go語言又在線程之上自己維護了Goroutine,所以針對Go進程的資源指標還需要加一個創建的Goroutine數量。

[[436282]]

談到讓Go程序監控自己進程的資源使用情況,那么就讓我們先來談一談有哪些指標是需要監控的,一般談論進程的指標最常見的就是進程的內存占用率、CPU占用率、創建的線程數。因為Go語言又在線程之上自己維護了Goroutine,所以針對Go進程的資源指標還需要加一個創建的Goroutine數量。

又因為現在服務很多都部署在Kubernetes集群上,一個Go進程往往就是一個Pod,但是容器的資源是跟宿主機共享的,只是在創建的時候指定了其資源的使用上限,所以在獲取CPU和Memory這些信息的時候還需要具體情況分開討論。

怎么用Go獲取進程的各項指標

我們先來討論普通的宿主機和虛擬機情況下怎么獲取這些指標,容器環境放在下一節來說。

獲取Go進程的資源使用情況使用gopstuil庫即可完成,它我們屏蔽了各個系統之間的差異,幫助我們方便地獲取各種系統和硬件信息。gopsutil將不同的功能劃分到不同的子包中,它提供的模塊主要有:

  • cpu:系統CPU 相關模塊;
  • disk:系統磁盤相關模塊;
  • docker:docker 相關模塊;
  • mem:內存相關模塊;
  • net:網絡相關;
  • process:進程相關模塊;
  • winservices:Windows 服務相關模塊。

我們這里只用到了它的process子包,獲取進程相關的信息。

聲明:process 模塊需要 import "github.com/shirou/gopsutil/process"后引入到項目,后面演示的代碼會用到的os等模塊會統一省略import相關的信息和錯誤處理,在此提前說明。

創建進程對象

process模塊的NewProcess會返回一個持有指定PID的Process對象,方法會檢查PID是否存在,如果不存在會返回錯誤,通過Process對象上定義的其他方法我們可以獲取關于進程的各種信息。

  1. p, _ := process.NewProcess(int32(os.Getpid())) 

進程的CPU使用率

進程的CPU使用率需要通過計算指定時間內的進程的CPU使用時間變化計算出來

  1. cpuPercent, err := p.Percent(time.Second

上面返回的是占所有CPU時間的比例,如果想更直觀的看占比,可以算一下占單個核心的比例。

  1. cp := cpuPercent / float64(runtime.NumCPU()) 

內存使用率、線程數和goroutine數

這三個指標的獲取過于簡單咱們就放在一塊說

  1. // 獲取進程占用內存的比例 
  2. mp, _ := p.MemoryPercent() 
  3. // 創建的線程數 
  4. threadCount := pprof.Lookup("threadcreate").Count() 
  5. // Goroutine數  
  6. gNum := runtime.NumGoroutine() 

上面獲取進程資源占比的方法只有在虛擬機和物理機環境下才能準確。類似Docker這樣的Linux容器是靠著Linux的Namespace和Cgroups技術實現的進程隔離和資源限制,是不行的。

現在的服務很多公司是K8s集群部署,所以如果是在Docker中獲取Go進程的資源使用情況需要根據Cgroups分配給容器的資源上限進行計算才準確。

容器環境下獲取進程指標

在Linux中,Cgroups給用戶暴露出來的操作接口是文件系統,它以文件和目錄的方式組織在操作系統的/sys/fs/cgroup路徑下,在 /sys/fs/cgroup下面有很多諸cpuset、cpu、 memory這樣的子目錄,每個子目錄都代表系統當前可以被Cgroups進行限制的資源種類。

針對我們監控Go進程內存和CPU指標的需求,我們只要知道cpu.cfs_period_us、cpu.cfs_quota_us 和memory.limit_in_bytes 就行。前兩個參數需要組合使用,可以用來限制進程在長度為cfs_period的一段時間內,只能被分配到總量為cfs_quota的CPU時間, 可以簡單的理解為容器能使用的核心數 = cfs_quota / cfs_period。

所以在容器里獲取Go進程CPU的占比的方法,需要做一些調整,利用我們上面給出的公式計算出容器能使用的最大核心數。

  1. cpuPeriod, err := readUint("/sys/fs/cgroup/cpu/cpu.cfs_period_us"
  2.  
  3. cpuQuota, err := readUint("/sys/fs/cgroup/cpu/cpu.cfs_quota_us"
  4.  
  5. cpuNum := float64(cpuQuota) / float64(cpuPeriod) 

然后再把通過p.Percent獲取到的進程占用機器所有CPU時間的比例除以計算出的核心數即可算出Go進程在容器里對CPU的占比。

  1. cpuPercent, err := p.Percent(time.Second
  2.  
  3. // cp := cpuPercent / float64(runtime.NumCPU()) 
  4.  
  5. // 調整為 
  6.  
  7. cp := cpuPercent / cpuNum 

而容器的能使用的最大內存數,自然就是在memory.limit_in_bytes里指定的啦,所以Go進程在容器中占用的內存比例需要通過下面這種方法獲取

  1. memLimit, err := readUint("/sys/fs/cgroup/memory/memory.limit_in_bytes"
  2.  
  3. memInfo, err := p.MemoryInfo 
  4.  
  5. mp := memInfo.RSS * 100 / memLimit 

上面進程內存信息里的RSS叫常駐內存,是在RAM里分配給進程,允許進程訪問的內存量。而讀取容器資源用的readUint,是containerd組織在cgroups實現里給出的方法。

  1. func readUint(path string) (uint64, error) { 
  2.  
  3. v, err := ioutil.ReadFile(path) 
  4.  
  5. if err != nil { 
  6.  
  7. return 0, err 
  8.  
  9.  
  10. return parseUint(strings.TrimSpace(string(v)), 10, 64) 
  11.  
  12.  
  13. func parseUint(s string, base, bitSize int) (uint64, error) { 
  14.  
  15. v, err := strconv.ParseUint(s, base, bitSize) 
  16.  
  17. if err != nil { 
  18.  
  19. intValue, intErr := strconv.ParseInt(s, base, bitSize) 
  20.  
  21. // 1. Handle negative values greater than MinInt64 (and
  22.  
  23. // 2. Handle negative values lesser than MinInt64 
  24.  
  25. if intErr == nil && intValue < 0 { 
  26.  
  27. return 0, nil 
  28.  
  29. else if intErr != nil && 
  30.  
  31. intErr.(*strconv.NumError).Err == strconv.ErrRange && 
  32.  
  33. intValue < 0 { 
  34.  
  35. return 0, nil 
  36.  
  37.  
  38. return 0, err 
  39.  
  40.  
  41. return v, nil 
  42.  

我在下方參考鏈接里會給出他們源碼的鏈接。

 

責任編輯:武曉燕 來源: 網管叨bi叨
相關推薦

2021-08-17 07:15:16

Github開源項目

2020-12-18 10:13:19

晉升職級協議

2020-08-31 08:14:46

Python開發代碼

2022-02-28 08:11:30

gopsutil網絡進程

2017-02-13 20:18:47

Windows 7Windows 10微軟

2021-11-15 23:47:19

手機內存技術

2022-08-29 08:41:52

異步ControllerrunAsync

2024-06-03 08:52:40

2020-09-09 09:46:57

手機NFC功能

2019-12-24 09:31:55

機器人人工智能編程

2018-01-05 12:45:25

社交網絡隱私應用程序

2024-11-29 08:53:46

2015-05-08 10:52:39

2022-11-11 08:31:39

Java注解注解類

2016-10-17 18:00:46

WIFIWIFI信號

2022-08-29 08:05:44

Go類型JSON

2014-08-13 11:20:10

創業者

2016-01-05 11:00:02

2012-07-25 09:56:52

編程程序員

2021-06-10 14:05:47

AI 芯片人工智能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲欧美综合 | 蜜桃视频在线观看www社区 | 九九九久久国产免费 | 亚洲一区二区久久 | 成人在线精品视频 | 69亚洲精品| 欧美激情在线精品一区二区三区 | 一级欧美视频 | 老司机67194精品线观看 | 久久精品免费观看 | 一级片在线播放 | 在线视频一区二区 | 成人超碰在线 | 激情欧美一区二区三区中文字幕 | av一二三区 | 日日夜夜精品 | 91美女在线观看 | 久久久久久国产精品免费免费男同 | 久久久国产一区 | 久草在线中文888 | 一级片在线播放 | a久久久久久 | 午夜激情影院 | 亚洲成人高清 | 欧美中文字幕一区二区三区 | 91久久久久久久久久久 | 一区二区中文 | 精品久久国产 | 欧美a级成人淫片免费看 | 国产视频中文字幕 | 自拍视频在线观看 | 亚洲免费大片 | 久久综合一区二区三区 | 亚洲精品中文字幕在线 | 精品国产一区二区三区久久久久久 | 羞羞视频免费在线观看 | 一级日韩 | 成人深夜福利在线观看 | 国产精品不卡一区 | 国产你懂的在线观看 | 狠狠爱综合|