Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在容器里怎么设置GOMAXPRCS #57

Open
kevinyan815 opened this issue Mar 25, 2021 · 1 comment
Open

在容器里怎么设置GOMAXPRCS #57

kevinyan815 opened this issue Mar 25, 2021 · 1 comment

Comments

@kevinyan815
Copy link
Owner

kevinyan815 commented Mar 25, 2021

GOMAXPROCS 是 Go 提供的非常重要的一个环境变量设定。通过设定 GOMAXPROCS,用户可以调整调度器中 Processor(简称P)的数量。由于每个系统线程,必须要绑定 P ,P 才能把G交给 M 执行。所以 P 的数量会很大程度上影响 Go Runtime 的并发表现。GOMAXPROCS 在版本 1.5后的默认值是机器的 CPU 核数 (runtime.NumCPU)。

package main

import (
	"fmt"
	"runtime"
)

func getGOMAXPROCS() int {
	_ :=  runtime.NumCPU() // 获取机器的CPU核心数
	return runtime.GOMAXPROCS(0) // 参数为零时用于获取设置的GOMAXPROCS
}

func main() {
	fmt.Printf("GOMAXPROCS: %d\n", getGOMAXPROCS())
}

而以 Docker 为代表的容器虚拟化技术,会通过 cgroup 等技术对 CPU 资源进行隔离。以 Kubernetes 为代表的基于容器虚拟化实现的资源管理系统,也支持这样的特性。这类技术对 CPU 的隔离限制,导致 runtime.NumCPU() 无法正确获取到容器被分配的 CPU 资源数。runtime.NumCPU()获取的是宿主机的核心数。

设置 GOMAXPROCS 高于真正可使用的核心数(宿主机的核心数/容器可使用的核心数)后会导致Go调度器不停地进行OS线程切换,从而给调度器增加很多不必要的工作。

目前 Go 官方并无好的方式来规避在容器里获取不到真正可使用的核心数这一问题,而 Uber 提出了一种 Workaround uber-go/automaxprocs。利用这一个包,可以在运行时根据 cgroup 或者 runtime 来修改 GOMAXPROCS。

import _ "go.uber.org/automaxprocs"

func main() {
  // Your application logic here.
}

参考资料:
https://gaocegege.com/Blog/maxprocs-cpu

https://stackoverflow.com/questions/36492356/parallel-programming-in-go-using-gomaxprocs/36492517#36492517

GMP调度器

@Browinee
Copy link

看不太懂@@ 但還是感謝分享XD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants