【问题标题】:Max. number of parallel background threads (backend)最大限度。并行后台线程数(后端)
【发布时间】:2012-12-18 15:47:04
【问题描述】:

我可以在一个谷歌应用引擎后端启动多少个并行后台线程?我没有找到任何有关并行允许线程数量的信息。我在 GAE 中使用 Java。

我按照文档中的说明开始了一个新线程:[1]

return ThreadManager.createBackgroundThread(new Runnable() { ... });

如果我运行我的应用程序,一段时间后会抛出以下异常(在创建新线程时):

com.google.appengine.api.system.SystemFailureException: An unknown error occurred

此 [2] 问题提到,如果 API 超出配额,则会出现此异常。所以我可以创建线程,但在一定时间后出现异常。这就是为什么我认为后端有线程限制。

[1]https://developers.google.com/appengine/docs/java/backends/overview#background_threads

[2]http://code.google.com/p/googleappengine/issues/detail?id=7398

【问题讨论】:

  • 什么时候开始看到这个问题?例如。当您创建一定数量的线程时会发生这种情况吗?默认后端实例类型仅来自with 128M of memory。根据每个线程的内存占用,您也可能会耗尽内存。在 Python GAE 应用程序中,您实际上可以measure the memory usage of your backend instance through the Runtime API
  • 我编辑了我的问题。是的,我可以毫无问题地在后端创建线程。我正在使用具有 512M 内存的 B4 后端,所以我不认为我的内存不足。但你是对的,当我创建了一定数量的线程时会发生这种情况(但我不知道有多少)。
  • 您能否重现该问题以确定发生这种情况时正在运行的线程数?
  • 我不能说允许多少线程,但我知道 GAE 有线程限制。我使用任务队列来调用我的后端并做一些工作。过了一会儿,一些任务失败了,但后端没有抛出错误。所以我认为如果达到线程限制,您将无法创建新的后台进程,也无法在后端启动新任务。因此,我不能说允许多少线程:(。我将创建一个答案并展示我或多或少是如何绕过这个问题的。

标签: java google-app-engine


【解决方案1】:

为了记录,App Engine 区分 normal threadsbackground threads,它不能超过启动它们的 HTTP 请求。

对于 Python,至少,看起来生产 (Python 2.7) 运行时和 dev_appserver 都施加了每个后端 10 个后台线程的固定限制,独立于 其他设置,例如max_concurrent_requestsbackends.yaml.

我与其他几位 App Engine 团队的老成员交谈过,虽然他们没有 100% 肯定,他们说这听起来是对的。我已经凭经验证实了 测试后端配置和下面的代码。我还尝试从一个单独的 HTTP 请求和另一个后台线程启动更多后台线程。没运气;相同的总限制为 10 个。

这里是 SDK 在 dev_appserver(特别是 SDK 1.8.8 中的 devappserver2)中为 Python 设置限制的地方: instance.py:449, python_runtime.py:61。 看起来 Go 和 Java 完全禁用了后台线程: go_runtime.py:99, java_runtime.py:61.

一个有趣的怪癖:在后台线程中,看起来您可以启动任意数量的正常线程,至少在达到内存限制之前是这样。他们没有打开任何 HTTP 请求,而且他们似乎也没有在截止日期前被切断。我目前正在这样做以解决后台线程限制。

我希望这被记录在案!会为我节省很多时间。


backends.yaml

- name: test
  instances: 1
  start: threadtest.application

test.py

def test():
  for i in range(100):
    logging.info('Starting #%d', i)
    background_thread.start_new_background_thread(time.sleep, [20])

class Start(webapp2.RequestHandler):
  def get(self):
    background_thread.start_new_background_thread(test, [])

application = webapp2.WSGIApplication([('/_ah/start', Start)], debug=True)

【讨论】:

    【解决方案2】:

    我的问题是后端的 API 限制。我可以启动任意数量的线程,但是当我达到 API 限制(100 个同时调用)时,就无法创建新线程了。 their docs 中描述了配额和限制。

    我减少了我的 API 调用(数据库、谷歌云存储)以加快应用程序的性能并且异常消失了 :)。

    【讨论】:

      【解决方案3】:

      鉴于例外情况,我假设您使用的是 Java。

      你是如何创建线程的?您应该使用 ThreadManager(而不是调用不支持的“new Thread()”)。

      后台线程是指后端的代码吗?您需要在后端任务中启动后台线程。

      为了记录,每个请求限制为 50 个线程。

      阅读线程here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-24
        • 2014-05-06
        • 2018-01-21
        相关资源
        最近更新 更多