GAE更新应用程序,如何避免长时间过程的暴力停止?

时间:2016-05-13 11:31:16

标签: python google-app-engine

我有一个GAE应用程序通过其他模块(由basic_scaling管理)产生一些长进程。

这个长进程正确处理DeadlineExceededError但产生了一个deferred方法,该方法将保存稍后将恢复的长进程的当前状态。

今天我发现当我做appcfg.py -A <YOUR_PROJECT_ID> update myapp/时,它会彻底停止漫长的过程。只是停下来,没有DeadlineExceededError(这是我的希望),没有。

在停止应用程序之前是否有一些GAE触发的事件会让我保存我的长进程的当前状态,将数据写入文件(通过s3,所以有点长),然后将进程重新排队 - 后来? (或类似的东西)?

感谢您的帮助。

2 个答案:

答案 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