我在几个平台上试验并发请求处理。
该实验的目的是对某些选定技术的容量界限进行广泛测量。
我在我的机器上设置了一个 Linux 虚拟机,它有一个基本的 Go http 服务器(http
默认包的 Vanilla http.HandleFunc
)。
然后服务器将计算 fasta 的修改版本 限制线程和进程为1的算法,并返回结果。 N 设置为 100000。
该算法运行大约 2 秒。
我在 Google App Engine 项目中使用了相同的算法和逻辑。
算法是使用相同的代码编写的,只是根据 GAE 要求,处理程序设置是在 init()
而不是 main()
上完成的。
在另一端,Android 客户端生成 500 个线程,每个线程并行向 fasta 计算服务器发出 GET
请求,请求超时为 5000 毫秒。
我原以为 GAE 应用程序能够扩展并响应每个请求,而本地 Go 服务器会在 500 个请求中的某些请求上失败,但结果恰恰相反: 本地服务器在超时范围内正确回复了每个请求,而 GAE 应用程序只能处理 500 个请求中的 160 个。其余请求超时。
我在 Cloud Console 上进行了检查,确认生成了 18 个 GAE 实例,但绝大多数请求仍然失败。
我以为大部分失败是因为每个GAE实例的启动时间,所以我马上重复了实验,但我得到了相同的结果:大多数请求都超时了。
我期待 GAE 能够扩展以容纳所有请求,我相信如果单个本地 VM 能够成功回复 500 个并发请求,GAE 也会做同样的事情,但事实并非如此。
GAE 控制台未显示任何错误并正确报告传入请求的数量。
这可能是什么原因? 此外,如果单个实例仅依靠 goroutine 就可以处理我机器上的所有传入请求,那么 GAE 为何需要如此大的扩展?
最佳答案
为了最大限度地降低成本,您需要在 app.yaml
中配置一些东西:
- 启用
threadsafe: true
- 实际上它来自Python config不适用于 Go,但我会设置它以防万一。 - 调整scaling section :
max_concurrent_requests
- 设置为最大值 80max_idle_instances
- 设置为最小值 0max_pending_latency
- 将其设置为自动或大于min_pending_latency
min_idle_instances
- 将其设置为 0min_pending_latency
- 设置为更高的数字。如果您可以接受 1 秒的延迟,并且您的处理程序平均需要 100 毫秒的时间来处理,则将其设置为 900 毫秒。
那么你应该能够在单个实例上处理大量请求。
如果您可以为了响应性和可扩展性而烧钱 - 增加 min_idle_instances
和 max_idle_instances
。
您是否也为 VM 和 GAE 使用类似的实例类型? GAE F1 实例不是太快,更适合处理 IO(数据存储、http 等)等异步任务。您可以配置使用更强大的实例以更好地扩展计算密集型任务。
您是否也在付费帐户上进行测试?免费帐户有配额,如果 AppEngine 认为如果连续使用相同的模式负载会超过每日配额,它会拒绝一定比例的请求。
关于google-app-engine - Google App Engine 上的并发请求处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47650500/