我有一个GAE应用程序通过其他模块(由basic_scaling管理)产生一些长进程。
这个长进程正确处理DeadlineExceededError但产生了一个deferred方法,该方法将保存稍后将恢复的长进程的当前状态。
今天我发现当我做appcfg.py -A <YOUR_PROJECT_ID> update myapp/
时,它会彻底停止漫长的过程。只是停下来,没有DeadlineExceededError(这是我的希望),没有。
在停止应用程序之前是否有一些GAE触发的事件会让我保存我的长进程的当前状态,将数据写入文件(通过s3,所以有点长),然后将进程重新排队 - 后来? (或类似的东西)?
感谢您的帮助。
答案 0 :(得分:1)
从Scaling types and instance classes开始,手动和基本缩放似乎与实例关闭前景相同:
与手动缩放一样,使用appcfg停止的实例也会停止 或者从云平台控制台)有30秒完成处理 请求被强行终止之前。
我假设在更新应用时使用相同的关机方法。
来自Shutdown:
应用有两种方法可以确定手动缩放 实例即将被关闭。首先,is_shutting_down() 来自google.appengine.api.runtime的方法开始返回true。第二 (并且首选),您可以注册一个关闭钩子,如下所述。
当App Engine开始关闭实例时,现有请求就是 给出30秒完成,新请求立即返回404。 如果实例正在处理请求,则App Engine会暂停该请求 并运行关闭钩子。如果没有活动请求,App Engine 发送/ _ah / stop请求,该请求运行shutdown hook。该 / _ah / stop请求绕过正常的处理逻辑,无法处理 按用户代码;它的唯一目的是调用关闭钩子。如果你 在处理另一个时,在关闭钩子中引发异常 请求,它会冒泡进入请求,你可以抓住它。
如果通过指定threadsafe:true启用了并发请求 在app.yaml(这是默认值)中,从a引发异常 shutdown hook将该异常复制到所有线程。以下代码 示例演示了一个基本的关闭钩子:
from google.appengine.api import apiproxy_stub_map from google.appengine.api import runtime def my_shutdown_hook(): apiproxy_stub_map.apiproxy.CancelApiCalls() save_state() # May want to raise an exception runtime.set_shutdown_hook(my_shutdown_hook)
或者,以下示例演示了如何使用 is_shutting_down()方法:
while more_work_to_do and not runtime.is_shutting_down(): do_some_work() save_state()
注意:识别关闭挂钩并不总是很重要 能够在实例终止之前运行。在极少数情况下,停电 可能会发生,阻止App Engine提供30秒 关机时间。因此,我们建议定期检查状态 你的实例主要用作内存缓存而不是 而不是一个可靠的数据存储。
基于我上面的假设,我希望这些方法也适用于你的情况,试试看。
答案 1 :(得分:1)
您似乎正在替换应用的现有version
(默认版本)。执行此操作时,它无法正常处理现有处理。
每当我更新我的应用程序的生产版本时,我都会在新版本中执行此操作。我使用当前日期作为我的版本名称(例如,2016-05-13)。然后我转到谷歌云控制台,将新版本作为默认版本。这样,旧版本继续并行运行。
几年前我问了一个类似的问题,你可以看到here。