【问题标题】:Running background thread in GAE flexible environment with Python-compact使用 Python-compact 在 GAE 柔性环境中运行后台线程
【发布时间】:2016-05-11 03:51:18
【问题描述】:

我正在将现有的 Python GAE(Google App Engine)标准环境应用程序迁移到柔性环境。我通读了guide 并决定尝试python-compact 运行时,因为尽可能多地重用代码总是好的。

在标准环境应用程序中,我们使用 background_thread.start_new_background_thread() 来生成一堆无限循环线程来永远处理一些后台工作。但是,即使对于一些非常简单的应用程序,我也无法让 start_new_background_thread 在灵活的环境中工作。喜欢这个示例应用程序: github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/background

在云中运行应用程序时,我不断收到以下error(虽然它在本地运行良好)。

我使用云调试器对其进行了调试,但是在 background_thread.py 中引发异常时根本没有任何错误消息

知道如何使用 python-compact 运行时在灵活的环境中运行长寿命的后台线程吗?谢谢!

【问题讨论】:

    标签: python google-app-engine background-thread app-engine-flexible


    【解决方案1】:

    App Engine 标准和 App Engine 灵活之间的区别之一是,我们实际上只是在运行一个 docker 容器。我可以想到 2 种方法来尝试。

    1。只需使用 Python 多处理

    App Engine 标准强制实施沙盒,这主要意味着不直接使用线程或进程。使用 Flex,您应该能够只使用标准 Python 库来启动新的子进程:

    https://docs.python.org/3/library/subprocess.html

    2。使用 supervisord 和 docker

    如果这不起作用,您可以在此处采用的另一种方法是自定义您在 Flex 中使用的 docker 映像,并使用 supervisord 启动多个进程。首先,通过 cd-ing 到包含源代码的文件夹并运行来生成 dockerfile:

    gcloud preview app gen-config --custom

    这将创建一个您可以自定义的 Dockerfile。现在,您将要启动 2 个进程 - 我们正在启动的进程(我认为对于 python-compat 它是 gunicorn)和您的后台进程。使用 docker 最简单的方法是使用 supervisord:

    https://docs.docker.com/engine/admin/using_supervisord/

    修改您的 Dockerfile 并添加一个 supervisord.conf 后,您可以像通常使用 gcloud preview app deploy 一样部署您的应用程序。

    希望这会有所帮助!

    【讨论】:

    • 谢谢@justin!我想尝试 python-compact 的主要原因是编写更少的代码来将现有的 GAE 应用程序迁移到新环境。我觉得 python-compact 运行时仍然存在一些差距。所以我决定用 gevent 在标准的 python 运行时重写它。感谢您的想法!
    【解决方案2】:

    我希望文档说 background_thread 不是受支持的 API。

    无论如何,我发现了一些技巧来帮助解决一些线程不兼容的问题。 App Engine 使用os.environ 读取大量设置。应用程序中的“真实”线程将在那里设置一堆环境变量。您启动的后台线程将没有。我使用的一种技巧是复制一些环境变量。例如,我需要在后台线程中复制设置 SERVER_SOFTWARE 变量,以使 App Engine 云存储库正常工作。我们使用类似的东西:

    _global_server_software = None
    _SERVER_SOFTWARE = 'SERVER_SOFTWARE'
    
    def environ_wrapper(function, args):
        if _global_server_software is not None:
            os.environ[_SERVER_SOFTWARE] = _global_server_software
        function(*args)
    
    def start_thread_with_app_engine_environ(function, *args):
        # HACK: Required for the cloudstorage API on Flexible environment threads to work
        # App Engine relies on a lot of environment variables to work correctly. New threads get none
        # of those variables. loudstorage uses SERVER_SOFTWARE to determine if it is a test instance
        global _global_server_software
        if _global_server_software is None and os.environ.get(_SERVER_SOFTWARE) is not None:
            _global_server_software = os.environ[_SERVER_SOFTWARE]
    
        t = threading.Thread(target=environ_wrapper, args=(
            function, args))
        t.start()
    

    【讨论】:

      猜你喜欢
      • 2017-06-30
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多