使用Python-compact在GAE灵活环境中运行后台线程

时间:2016-05-11 03:51:19

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

我正在努力将现有的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运行时在灵活的环境中运行长寿命后台线程吗?谢谢!

2 个答案:

答案 0 :(得分:2)

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

1。只需使用Python多处理

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

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

2。使用supervisord和docker

如果这不起作用,您可以采取的另一种方法是自定义您在Flex中使用的泊坞窗图像,并使用supervisord启动多个流程。首先,通过cd-into到源文件夹并运行:

生成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部署应用程序。

希望这有帮助!

答案 1 :(得分:2)

我希望文档说os.environ不是受支持的API。

无论如何,我发现了一些黑客可以帮助解决某些线程不兼容问题。 App Engine使用SERVER_SOFTWARE来读取大量设置。 "真实"应用程序中的线程将在那里设置一堆环境变量。你启动的后台线程将没有。我曾经使用的一个方法是复制一些环境变量。例如,我需要在后台线程中复制设置_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() 变量,以使App Engine云存储库正常工作。我们使用类似的东西:

click=(action 'myActionName')