【问题标题】:Do I need to spawn multiple Go web server instances to fully utilize my CPU?我是否需要生成多个 Go Web 服务器实例才能充分利用我的 CPU?
【发布时间】:2018-02-23 12:22:17
【问题描述】:

我不完全确定如何提出这个问题,但根据我使用 NodeJS 的经验,它有一个线程和一个进程队列来管理异步函数,你需要在单独的进程上运行你的 web 服务器的每个实例CPU 线程 - 然后在每个实例之间进行负载平衡。

您最终可以运行相同软件的 4 个实例,在 4 个单独的端口上提供服务,并通过负载平衡器在一个端口上公开。

通常,您会使用 PM2 之类的服务来为您管理此流程。

根据我的(基本)理解,goroutines 不是线程,所以我的自然思维想知道这是否意味着 Go 需要以相同的方式运行,多个进程跨越每个 CPU 线程。

是这样吗?或者,如果我使用 Gin 之类的东西编写 REST API,Go 会随着需求的增加自动跨 CPU 线程扩展吗?

【问题讨论】:

  • “根据我的(基本)理解,goroutines 不是线程”这是正确的,但您可以配置 go 使用多少线程来运行这些 goroutines。
  • Goroutines 被调度在真正的 OS 线程上。是的,标准库http 服务器会生成一个 goroutine 来处理每个连接,这将利用进程可用的所有 CPU。
  • @zerkms - 太好了!从 tkausl 所说,听起来设置最大可用线程是一个手动过程,是这种情况还是该过程会根据需要自动增长?
  • @DavidAlsh 如果您想利用所有 CPU,则无需设置任何内容。默认情况下,运行时设置为利用所有。

标签: go go-gin


【解决方案1】:

几乎每个 Go 网络服务器都基于 net/http 并在 http.Server 上调用(最终)http.ListenAndServe()。 (在杜松子酒中,router.Run() 包装了这个。)http.Server 的文档解释了它:

调用 Serve 处理传入连接的请求。

http.Serve() 做接受连接的真正工作,

为每个服务创建一个新的 goroutine。

Goroutines 比 OS 线程更轻量;每个线程可以运行许多 goroutine。因此,您的应用程序可能会提供数十个(或数百个或更多?) 单个进程上的同时连接数。

默认情况下,Go 将使用所有可用的处理器内核;如果您有一些迫切需要使用所有处理器内核,您可以设置GOMAXPROCSenvironment variable

GOMAXPROCS 变量限制了可以同时执行用户级 Go 代码的操作系统线程数。代表 Go 代码在系统调用中可以阻塞的线程数没有限制;这些不计入 GOMAXPROCS 限制。这个包的 GOMAXPROCS 函数查询和更改限制。

因此,您无需与 PM2 或主管等奇怪的流程管理器混为一谈;你可以从一个普通的 systemd 单元启动你的服务器,或者作为 Docker 容器中的 PID 1,然后享受(但收获你的孩子)。

【讨论】:

    猜你喜欢
    • 2019-08-07
    • 2013-06-17
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多