我不太确定如何问这个问题,但根据我使用 NodeJS 的经验,NodeJS 有一个线程和一个进程队列来管理异步函数,您需要在每个 CPU 线程的单独进程上运行一个 Web 服务器实例 -然后在每个实例之间进行负载平衡。
您最终可能会运行同一软件的 4 个实例,在 4 个独立的端口上提供服务,并通过负载均衡器在一个端口上公开。
通常,您会使用 PM2 等服务来为您管理此流程。
根据我(基本)的理解,goroutines 不是线程,所以我的自然思维想知道这是否意味着 Go 需要以相同的方式运行,每个 CPU 线程跨越多个进程。
是这样吗?或者,如果我使用 Gin 之类的东西编写 REST API,Go 会随着需求的增加自动跨 CPU 线程扩展吗?
事实上,每个 Go Web 服务器都基于net/http
并(最终)http.ListenAndServe()
调用http.Server
. (在杜松子酒中,router.Run()
将其包装起来。)文档http.Server
解释说:
调用 Serve 来处理传入连接上的请求。
http.Serve()
真正完成接受连接的工作,
为每个服务创建一个新的服务 goroutine。
Goroutines 比 OS 线程更轻;每个线程可以运行多个 goroutine。因此,您的应用程序可能会在单个进程上同时服务数十个(或数百个或更多?)连接。
默认情况下,Go 将使用所有可用的处理器内核;如果您迫切需要不使用所有处理器核心,则可以设置GOMAXPROCS
环境变量。
GOMAXPROCS 变量限制可以同时执行用户级 Go 代码的操作系统线程的数量。代表 Go 代码在系统调用中可以阻塞的线程数量没有限制;这些不计入 GOMAXPROCS 限制。该包的 GOMAXPROCS 函数查询并更改限制。
因此,您无需与 PM2 或主管等奇怪的流程经理打交道;你可以从普通的 systemd 单元启动你的服务器,或者在 Docker 容器中作为 PID 1 启动你的服务器,然后享受(但收获你的孩子)。