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

huangapple go评论85阅读模式
英文:

How does Go handle concurrent request on Google App Engine

问题

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

以下是我收集到的事实:

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

  2. Goroutines被多路复用到多个操作系统线程上,所以如果一个goroutine被阻塞,比如在等待I/O时,其他goroutines会继续运行。

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

如果Go在App Engine上是单线程的,那么第3点就没有意义了。这就只剩下了第1点和第2点。如果Go在App Engine上是单线程的,并且在等待I/O时需要继续执行线程,那么似乎一个App Engine Go实例将在等待I/O时阻塞所有的goroutines。

这样对吗?如果不是,Go在App Engine上的并发性是如何工作的?

为了帮助量化问题。如果我保持一个连接开放30秒,一个单独的AE Go实例可以维持多少并发连接?

谢谢。

> 编辑:这是一个功能请求,允许Go实例处理超过10个并发请求的Allow configurable limit of concurrent requests per instance。请给它点赞。

英文:

I'm a little confused on how Go handles concurrent requests on Google App Engine. So I'm hoping someone can provide some clarity.

Here are the facts that I have gathered:

  1. Go is single threaded on 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.

If Go is single threaded on App Engine then point 3 is moot. This leaves 1 and 2. If Go on App Engine is single threaded and threads are required to continue execution while blocking for I/O, then it seems that an App Engine Go instance will block all goroutines while waiting on I/O.

Is this correct? If not how does Go's concurrency really work on App Engine?

To help quantify things. If I were to hold a connection open for 30 seconds. How may concurrent connections could a single AE Go instance maintain?

Thank you.

> EDIT: here's the feature request which will allow Go Instance to
> handle more then 10 concurrent request Allow configurable limit of
> concurrent requests per
> instance
.
> Please star it.

答案1

得分: 22

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

你的说法“如果Go在App Engine上是单线程的,那么第3点就没有意义。”是不正确的。对于单个Go App Engine实例,仍然存在10个并发的正在进行中的请求的限制。当文档谈到“线程”时,措辞有些不严谨。

英文:

A Go App Engine instance allows 10 concurrent requests, but only runs one CPU thread. In effect, multiple requests can be processed concurrently, but only one will be able to do CPU work at a time. If one request is, say, waiting for a datastore API call to return, another request is free to be processed by the same instance.

Your statement "If Go is single threaded on App Engine then point 3 is moot." is incorrect. There is still a limit of 10 concurrent in-flight requests to a single Go App Engine instance. The documentation is a bit loose with words when it talks about "threads".

答案2

得分: 4

我必须承认,我对AppEngine没有内部知识。这只是一种猜测,但我认为这是合理的。

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

并发性不受影响,因为最终,在appengine中您所做的一切都归结为等待网络返回的某些内容。您不需要多个线程同时执行多个任务。

英文:

I must admit I have no inside knowledge of AppEngine. This is all speculation and guessing, but I think it is somewhat reasonable.

Your app will never reach the ten thread limit. This is because there are very few reasons for threads to be created. First, the maximum number of goroutines running at once is set to one to enforce memory safety. Second, unlike a normal go program, app engine does not actually need to make syscalls. The only time it does is for networking. All IO in appengine can be muxed into one epoll thread. This means all you need is two threads at any given time. You can then add a third or forth thread in case every once in a while you need to run other syscalls such as allocating memory and accepting/closing connections. These are fast syscalls that block for a very small amount of time. Even with these other syscalls, you are still very far from the ten thread limit.

Concurrency is not affected because in the end, everything you do in appengine boils down to waiting for something over the network to return. You do not need multiple threads to be doing many things at once.

答案3

得分: 1

我正在寻找一个答案,偶然间遇到了这个问题/答案,但也找到了更多关于这个问题的官方文档。根据Andrew Gerrand和Johan Euphrosine的帖子,这可以被明确地配置。

从那篇帖子中:

> 这将配置每个应用实例同时处理最多100个请求(默认为10个)。你可以将Go实例配置为同时处理最多500个请求。

英文:

I was looking for an answer and happened upon this question/answers, but also ended up finding more official documentation on the matter. According to a post by Andrew Gerrand and Johan Euphrosine this can be explicitly configured.

From that post:

> This configures each instance of the app to serve up to 100 requests concurrently (up from the default of 10). You can configure Go instances to serve up to a maximum of 500 concurrent requests.

huangapple
  • 本文由 发表于 2012年7月12日 15:05:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/11446602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定