在 gorilla/mux 框架中使用 Go 例程

Using Go routines in gorilla/mux framework

我们正在使用大猩猩 mux 框架来处理网络请求,我想它会自动在所有 cpu 核心上运行。在这种情况下使用 go routines 对于 cpu 密集型进程(例如循环遍历一个大对象)有好处吗?

I suppose automatically runs on all the cpu cores.

你猜错了。有点。

从 Go 1.5 开始,Go 将通过 运行在不同内核上设置 go 例程来使用所有内核。但是如果你不使用go routines,它就没有办法利用这个。

Is there a benefit of using go routines in such a case for cpu intensive processes for eg looping through a large object?

可以的。但是你问错了问题。

您不使用 Go 例程主要是为了利用不同的 CPU 核心(尽管这也可能是一个好处)。您使用 Go 例程来防止您的程序在执行需要一段时间的操作时阻塞。

对于 Web 应用程序,大多数请求通常 不是 CPU 密集型。但他们通常会花很多时间(用计算机术语来说)等待事情发生。他们等待请求主机名上的 DNS 查找,他们等待数据库查找用户凭据以建立会话,他们等待数据库存储或 return 行以产生 HTTP 响应,等等

如果没有 go 例程,在执行这些操作时,您的服务器将无法执行任何其他操作。因此,如果您的典型 HTTP 请求花费了比方说 1 秒的时间来查找 DNS、验证授权 cookie、从数据库中查找结果并发送响应,则无法同时为其他 HTTP 客户端提供服务。

幸运的是,Gorilla(以及几乎所有其他 Go 网络框架)使用的 http 已经使用 Go 例程 来处理请求。因此,您已经(至少)为每个 HTTP 请求使用了一个 Go 例程。

使用额外的 go 例程是否有意义比 "using more CPU cores."

更取决于您的应用程序设计

一些建议:

  1. 如果您要执行多项操作来满足可以并行完成的请求,请使用 go routines。假设你需要做 3 个数据库查询,你可以在一个 Go 例程中做每一个,所以它们 运行 同时进行。它们可能 运行 在不同的 CPU 核心上,但这与实际性能完全无关,因为每个核心实际上什么都不做,只是在等待数据库。但是您仍然会提高性能。 (为了完整起见,我会提到 goroutines 不是 运行 数据库并行查询的唯一方法——但它们是惯用的 Go 方法,也是 Go 中最简单的方法)。
  2. 如果您有通过 HTTP 请求 运行 但不影响 HTTP 响应的任务,您可以在 Go 例程中 运行 它们,因此您的响应可以 return 早点。日志记录是一个常见的例子。您可能想要记录您的 HTTP 请求,但如果记录器速度很慢,您可能不希望在发送 HTTP 响应之前等待记录完成。所以在 go 例程中进行。记录器可以花点时间在 客户端已经收到他们的响应后 完成。另一个例子是发送电子邮件——请不要在响应 HTTP 客户端之前等待电子邮件发送。