Golang1.11.5编译的程序在运行时导致CPU占用100%
Golang1.11.5编译的程序在运行时导致CPU占用100%
环境:Windows 2016 Server + IIS(8个进程)+ Go 1.11.5
程序:
package main
import "fmt"
func main(){
fmt.println("hello, golang")
}
# go build -o hello.exe hello.go
结果:运行该程序会导致IIS CPU使用率达到100%。而在其他环境中该程序运行正常。
注意:当IIS工作进程数量 ≤ 4时,hello.exe运行正常;当进程数 > 4时,hello.exe会导致IIS进程占用100% CPU。
更多关于Golang1.11.5编译的程序在运行时导致CPU占用100%的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果发生这种情况,向开发者报告此问题以了解他们的观点可能是个好主意。请点击此链接进行操作。
我通过命令行编译,使用的命令是:
go build -o hello.exe hello.go
hello.exe 在其他所有 Windows 系统上都能正常运行,只有在 Windows Server 2016 + IIS 环境下才会遇到这个问题。
我检查了环境,GOARCH 是 amd64。不仅是 go1.11.5,其他版本如 go1.8.7、go1.9.7 等也存在这个问题。
我确信这种情况非常奇怪,就像运行一个"Hello World"程序却让服务器负载达到100%一样。一个可能的起点是检查GOARCH架构和正确的Go编译器版本(很可能应该是amd64)。
你是如何编译和运行这个程序的?是通过cmd.com还是PowerShell?或者你使用了集成开发环境?
如果你还没尝试过,请直接从命令行运行编译器(例如使用go build hello.go),而不是通过集成开发环境。
你还可以使用一个更简单的Go程序:
package main
func main() {}
该程序运行时不会执行任何操作。
这是一个典型的并发资源竞争问题,可能是Go运行时与IIS进程模型之间的交互导致的。问题很可能出现在Go 1.11.5的调度器与IIS工作进程竞争CPU资源时。
以下是可能导致问题的原因和解决方案:
问题分析
当IIS工作进程超过4个时,Go程序可能与IIS进程在CPU调度上产生冲突。Go的运行时调度器使用多个OS线程来执行goroutines,这可能与IIS的进程管理产生资源竞争。
解决方案
1. 限制Go程序的CPU使用
package main
import (
"fmt"
"runtime"
)
func main() {
// 限制程序使用的CPU核心数
runtime.GOMAXPROCS(2) // 设置为2个CPU核心
fmt.Println("hello, golang")
// 防止程序立即退出
select {}
}
2. 使用环境变量控制Go运行时
在运行程序前设置环境变量:
set GOMAXPROCS=2
hello.exe
3. 改进程序结构,避免空循环
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("hello, golang")
// 如果是长期运行的服务,添加适当的休眠
for {
time.Sleep(time.Minute) // 每分钟执行一次
// 实际的工作逻辑
}
}
4. 升级Go版本
Go 1.11.5相对较旧,建议升级到更新的版本(如Go 1.19+),新版本的调度器有更好的性能和资源管理:
# 使用新版Go重新编译
go build -o hello_new.exe hello.go
5. 在IIS中配置应用程序池
修改IIS应用程序池设置:
- 减少"最大工作进程数"
- 设置合适的"CPU限制"
- 启用"处理器关联掩码"
编译命令保持不变
go build -o hello.exe hello.go
主要问题在于Go运行时在Windows Server 2016 + IIS环境下对CPU资源的过度竞争。通过限制GOMAXPROCS或升级Go版本通常可以解决这个问题。

