15

我对 Go 如何处理 Google App Engine 上的并发请求有点困惑。所以我希望有人可以提供一些澄清。

以下是我收集到的事实:

  1. Go 在 App Engine 上是单线程的。-这是因为可以通过创建多个线程的竞争条件来进行任意指针运算

  2. Goroutine 被多路复用到多个 OS 线程上,因此如果一个线程阻塞,例如在等待 I/O 时,其他线程会继续运行。

  3. [App Engine 有一个] 10 个并发限制 [这是通过限制每个运行时的并发线程来实施的。在大多数情况下,我们的调度程序会尝试启动一个新实例。

如果 Go 在 App Engine 上是单线程的,那么第 3 点就没有实际意义。这留下了 1 和 2。如果 App Engine 上的 Go 是单线程的,并且线程需要在阻塞 I/O 时继续执行,那么看起来 App Engine Go 实例将在等待 I/O 时阻塞所有 goroutine。

它是否正确?如果不是,Go 的并发性如何在 App Engine 上真正发挥作用?

帮助量化事物。如果我要保持连接打开 30 秒。单个 AE Go 实例如何维持并发连接?

谢谢你。

编辑:这是允许 Go Instance 处理超过 10 个并发请求的功能请求Allow configured limit of concurrent requests per instance。请给它加星。

4

3 回答 3

22

一个 Go App Engine 实例允许 10 个并发请求,但只运行一个 CPU 线程。实际上,可以同时处理多个请求,但一次只能有一个可以做 CPU 工作。例如,如果一个请求正在等待数据存储 API 调用返回,则另一个请求可以由同一实例自由处理。

您的陈述“如果 Go 在 App Engine 上是单线程的,那么第 3 点没有实际意义。” 是不正确的。对单个 Go App Engine 实例仍有 10 个并发进行中请求的限制。当谈到“线程”时,文档有点松散。

于 2012-07-16T05:32:35.643 回答
4

我必须承认我对 AppEngine 没有内幕。这都是猜测和猜测,但我认为这有些合理。

您的应用永远不会达到十个线程的限制。这是因为创建线程的原因很少。首先,一次运行的 goroutine 的最大数量设置为 1 以强制执行内存安全。其次,与普通的 go 程序不同,应用引擎实际上不需要进行系统调用。它唯一的作用是用于网络。appengine 中的所有 IO 都可以复用到一个 epoll 线程中。这意味着您在任何给定时间只需要两个线程。然后,您可以添加第三个或第四个线程,以防不时需要运行其他系统调用,例如分配内存和接受/关闭连接。这些是阻塞时间非常短的快速系统调用。即使使用这些其他系统调用,您仍然离十个线程的限制很远。

并发不会受到影响,因为最终,您在 appengine 中所做的一切都归结为等待网络上的某些内容返回。您不需要多个线程一次做很多事情。

于 2012-07-12T22:50:43.053 回答
1

我一直在寻找答案并偶然发现了这个问题/答案,但最终也找到了有关此事的更多官方文档。根据Andrew Gerrand 和 Johan Euphrosine 的帖子,这可以显式配置。

从那个帖子:

这会将应用程序的每个实例配置为同时处理最多 100 个请求(默认为 10 个)。您可以将 Go 实例配置为最多处理 500 个并发请求。

于 2020-03-30T02:02:46.893 回答