我正在努力将现有的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运行时在灵活的环境中运行长寿命后台线程吗?谢谢!
答案 0 :(得分:2)
App Engine标准和App Engine灵活性之间的区别之一是,使用Flex我们实际上只是运行一个docker容器。我可以想到两种尝试的方法。
App Engine标准强制实施沙箱,这主要意味着不直接使用线程或进程。使用Flex,您应该能够使用标准Python库来启动新的子流程:
https://docs.python.org/3/library/subprocess.html
如果这不起作用,您可以采取的另一种方法是自定义您在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')