优化CPU密集型Golang WebApp的方法

优化CPU密集型Golang WebApp的方法,go,webserver,Go,Webserver,我有一个非常cpu密集的玩具web应用程序 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 -

我有一个非常cpu密集的玩具web应用程序

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)
}
操作系统参数-

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线程。此处描述了设计:,它引用了本文:

关于这些问题:

即使500个并发请求到达服务器,操作系统线程的数量仍然停留在35个操作系统线程上[…]有人能解释一下这种行为吗

由于您将GOMAXPROCS设置为CPU的数量,go一次只能运行那么多GoRoutine

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

操作系统级线程的创建由调度程序处理,系统级调用会带来额外的复杂性。有时,你需要一个真正的,专门的线程。看:但是你不应该期望有大量的线程

操作系统线程的数量可以通过操作系统或GOlang的方式增加吗

我认为使用LockOSThread可能会创建新线程,但这并不重要:

如果操作系统线程数量增加,这会提高性能吗

不,你的CPU在一次可以做多少事情上基本上是有限的。Goroutines之所以能工作,是因为事实证明,大多数操作在某种程度上都是IO限制的,但如果你真的在做CPU限制的事情,那么在这个问题上抛出更多的线程是没有帮助的。事实上,这可能会使情况变得更糟,因为在线程之间切换涉及到开销

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

有人能推荐一些其他优化此应用程序的方法吗

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

您最好的选择是找到一种优化代码的方法,以减少CPU时间。如果这是不可能的,它已经高度优化了,那么您将需要添加更多的计算机/CPU到组合中。买一台更好的电脑,或者更多

对于多台计算机,您可以将负载平衡器放在所有计算机的前面,这样可以很容易地进行扩展


您还可以从Web服务器中删除这项工作,并将其移动到某个后端系统。考虑使用一个工作队列。

< P>多个GORDOTIN可以对应于单个OS线程。此处描述了设计:,它引用了本文:

关于这些问题:

即使500个并发请求到达服务器,操作系统线程的数量仍然停留在35个操作系统线程上[…]有人能解释一下这种行为吗

由于您将GOMAXPROCS设置为CPU的数量,go一次只能运行那么多GoRoutine

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

操作系统级线程的创建由调度程序处理,系统级调用会带来额外的复杂性。有时,你需要一个真正的,专门的线程。看:但是你不应该期望有大量的线程

操作系统线程的数量可以通过操作系统或GOlang的方式增加吗

我认为使用LockOSThread可能会创建新线程,但这并不重要:

如果操作系统线程数量增加,这会提高性能吗

不,你的CPU在一次可以做多少事情上基本上是有限的。Goroutines之所以能工作,是因为事实证明,大多数操作在某种程度上都是IO限制的,但如果你真的在做CPU限制的事情,那么在这个问题上抛出更多的线程是没有帮助的。事实上,这可能会使情况变得更糟,因为在线程之间切换涉及到开销

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

有人能推荐一些其他优化此应用程序的方法吗

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

您最好的选择是找到一种优化代码的方法,以减少CPU时间。如果这是不可能的,它已经高度优化了,那么您将需要添加更多的计算机/CPU到组合中。买一台更好的电脑,或者更多

对于多台计算机,您可以将负载平衡器放在所有计算机的前面,这样可以很容易地进行扩展

您还可以从Web服务器中删除这项工作,并将其移动到某个后端系统。考虑使用工作队列。

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
for i := 0; i < 200000000; i++ {
   x = x + 1
   x = x - 1
}