gpt4 book ai didi

go - 优化 CPU 密集型 Golang WebApp 的方法

转载 作者:IT王子 更新时间:2023-10-29 01:55:24 26 4
gpt4 key购买 nike

我有一个玩具网络应用程序,它非常占用 CPU

func PerfServiceHandler(w http.ResponseWriter, req *http.Request) 
{
start := time.Now()
w.Header().Set("Content-Type", "application/json")

x := 0
for i := 0; i < 200000000; i++ {
x = x + 1
x = x - 1
}
elapsed := time.Since(start)
w.Write([]byte(fmt.Sprintf("Time Elapsed %s", elapsed)))
}

func main()
{
http.HandleFunc("/perf", PerfServiceHandler)
http.ListenAndServe(":3000", nil)
}

上述函数执行大约需要 120 毫秒。但是当我用 500 个并发用户(siege -t30s -i -v -c500 http://localhost:3000/perf)对这个应用程序进行负载测试时,我得到的结果是

  • 每个请求的平均响应时间 2.51 秒
  • 交易率每秒 160.57 个交易

有人可以回答我下面的问题吗:-

  • 当我运行 100、200、500 个并发用户时,我看到了编号。上述应用程序使用的操作系统线程数在应用程序刚启动时从 7 个卡在了 35 个。增加 no.of concurrent connection 不会改变这个数字。即使有 500 个并发请求到达服务器,操作系统线程数仍然停留在 35 个操作系统线程(该应用程序以 runtime.GOMAXPROCS(runtime.NumCPU()) 启动)。当测试停止时,数字仍然是 35。
    • 有人可以向我解释这种行为吗?
    • 可以吗?操作系统线程的数量以某种方式增加(从操作系统或从 Golang)?
    • 如果否,这会提高性能吗?增加了操作系统线程?
  • 有人可以建议一些其他优化此应用的方法吗?

环境:-

Go - go1.4.1 linux/amd64
OS - Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
Processor - 2.6Ghz (Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz)
RAM - 64 GB

操作系统参数-

nproc - 32
cat /proc/sys/kernel/threads-max - 1031126
ulimit -u - 515563
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 515563
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65536
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 515563
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

最佳答案

多个goroutine可以对应一个os线程。此处描述了设计:https://docs.google.com/document/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw/edit ,引用本文:http://supertech.csail.mit.edu/papers/steal.pdf .

关于问题:

Even when 500 concurrent requests arrive at the server the number of OS threads were still stuck at 35 OS threads [...] Can someone explain me this behaviour?

由于您将 GOMAXPROCS 设置为 CPU 的数量,因此 go 一次只会运行那么多 goroutine。

可能有点令人困惑的一件事是 goroutines 并不总是运行(有时它们“很忙”)。例如,如果您读取一个文件,当操作系统正在执行该工作时,goroutine 很忙,调度程序将选择另一个 goroutine 来运行(假设有一个)。一旦文件读取完成,goroutine 就会回到“可运行”goroutines 列表中。

操作系统级线程的创建由调度程序处理,并且系统级调用具有额外的复杂性。 (有时您需要一个真正的专用线程。请参阅:LockOSThread)但您不应期望有大量线程。

Can the no. of OS threads be increased somehow (from OS or from GOlang)?

我认为使用 LockOSThread 可能会导致创建新线程,但这无关紧要:

Will this improve the performance if no. of OS threads are increased?

没有。您的 CPU 从根本上限制了它一次可以做多少事情。 Goroutines 之所以有效,是因为事实证明大多数操作在某种程度上都是 IO 绑定(bind)的,但如果你真的在做一些 CPU 绑定(bind)的事情,那么在这个问题上投入更多的线程将无济于事。事实上,这可能会使情况变得更糟,因为在线程之间切换会产生开销。

换句话说,Go 在这里做出了正确的决定。

Can someone suggest some other ways of optimizing this app?

for i := 0; i < 200000000; i++ {
x = x + 1
x = x - 1
}

我想你写这段代码只是为了让 CPU 做很多工作?实际代码是什么样的?

您最好的选择是找到一种方法来优化该代码,从而减少它需要的 CPU 时间。如果那不可能(它已经高度优化),那么您将需要添加更多计算机/CPU。获得更好的计算机,或更多。

对于多台计算机,您可以在所有计算机前面放置一个负载均衡器,这应该很容易扩展。

您还可以通过将这项工作从网络服务器中分离出来并将其移动到某个后端系统而受益。考虑使用工作队列。

关于go - 优化 CPU 密集型 Golang WebApp 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30062703/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com