Go如何处理Google App Engine上的并发请求

问题描述:

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

下面是我收集到的事实:

  1. 围棋是单线程在App Engine上。 - this is because it is possible to do arbitrary pointer arithmetic by creating race conditions with multiple threads

  2. Goroutines are multiplexed onto multiple OS threads so if one should block, such as while waiting for I/O, others continue to run.

  3. [App Engine has a] 10 concurrent limit [which] is enforced through a limit on concurrent threads on every runtime. Most of such cases, our scheduler will try to spin up a new instance.

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

这是正确的吗?如果不是,Go的并发性如何在App Engine上真正起作用?

帮助量化事情。如果我打开连接30秒。单个AE Go实例可能会如何维护并发连接?

谢谢。

编辑:这里的功能要求,这将允许进入实例来 处理更多然后10个并发请求Allow configurable limit of concurrent requests per instance。 请明星。

+7

设置GOMAXPROCS = 1(这就是GAE所做的)只是意味着总会有一个执行goroutine的活动线程。你可能仍然有一对被阻塞的线程(它们不计数)。还要注意,Go库在后台使用epoll,因此I/O不太可能会阻塞整个线程(但在Go中还有其他几种方法来阻塞线程)。尽管如此,我对GAE的通用10线程限制一无所知。 – tux21b 2012-07-12 07:29:27

+1

并发请求限制现在可以配置(最多可达80),请参阅http://*.com/a/37364981/943833 – Roganartu 2016-05-21 15:49:38

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

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

+3

**这个答案需要更大的传播**我明白Go运行时会对请求进行排队,以便传入的请求必须等到当前请求完全处理完毕。很明显,一个请求可能产生许多去程序并且同时运行,但并不是很多程序可以运行。 – mjibson 2012-07-16 06:22:06

+0

文档确实会说“多个请求可能由给定实例同时处理”,但直到我刚刚重新读取它,我停止了单线程限制之前,我从来没有深入过这段话。 – mjibson 2012-07-16 06:28:01

+0

谢谢大卫。在请求限制方面我还有点不清楚。我在[Takashi的回应](http://*.com/a/11443482/236564)中表示所有由10个并发线程限制的实例,而不是请求。看来这最近可能已经改变了。对Go来说这不是真的吗?如果它确实是线程,F1Go实例可以处理的并发请求数量的实际限制是什么? – 2012-07-16 14:50:17

我必须承认我没有AppEngine的内部知识。这是所有猜测和猜测,但我认为这是有点合理的。

您的应用永远不会达到十个线程限制。这是因为创建线程的原因很少。首先,一次运行的最大套餐数量设置为1到enforce memory safety。其次,与普通的go程序不同,app引擎实际上并不需要进行系统调用。唯一的一次是联网。 appengine中的所有IO都可以混合成一个epoll线程。这意味着您在任何时候都需要两个线程。然后,您可以添加第三或第四个线程,以便每隔一段时间您需要运行其他系统调用,例如分配内存和接受/关闭连接。这些是快速的系统调用,可以阻塞很短的时间。即使有了这些其他系统调用,你仍然离十个线程的限制还很远。

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

+0

谢谢斯蒂芬,这非常有帮助。 – 2012-07-13 00:32:25

+0

@KyleFinley,如果你不太熟悉那个“epoll stuff”,我建议至少浏览一下经典的[“C10K问题”](http://www.kegel.com/c10k.html)工作。 – kostix 2012-07-13 08:07:29

+0

@kostix有趣的文章。谢谢。 – 2012-07-13 17:54:24