【问题标题】:How to use Modules in Google App Engine and add a target to them using Task Queue (Java)?如何在 Google App Engine 中使用模块并使用任务队列(Java)向它们添加目标?
【发布时间】:2025-12-17 21:05:02
【问题描述】:

我的任务超过了任务队列的 10 分钟截止时间。通过不同的文档,我发现使用模块我可以运行一个实例来处理长时间运行的任务,但最好甚至应该使用任务队列来完成。我曾使用过后端,但它们已被弃用。

我的问题是如何将模块引入我现有的 App Engine 项目以及如何使用它们来运行长时间运行的任务?

以下是一段代码:

Queue queue = QueueFactory.getQueue("myqueue");
TaskOptions task = TaskOptions.Builder.withUrl("/submitworker").method(Method.POST);
queue.add(task);

我必须在上述代码中进行哪些更改才能使用模块添加长时间运行的任务? [“submitworker”是一个 servlet,它是实际长时间运行的任务]

我已经推荐了this 链接,但我无法完成第三步:
3.将服务声明元素添加到 appengine-application.xml 文件中。

另外,即使我成功地将一个模块添加到我的项目中,我如何使用任务队列来定位这个模块?

我已经处理过this 的问题,但它是一个python 实现,我的实现是用Java 实现的。

我正在寻找有关如何在模块中使用“目标”以及如何在添加到任务队列时使用它的逐步过程。

即使我将长时间运行的模块目标添加到任务队列中,它仍然会在 10 分钟后终止执行,还是即使任务队列中的任务过期它也会完成任务?

请提出建议。

【问题讨论】:

    标签: java google-app-engine task-queue app-engine-modules gae-backends


    【解决方案1】:

    免责声明:答案完全基于文档(我实际上使用的是 python - 相同的概念但不同的配置)。

    要使服务/模块允许长时间运行的任务,您必须将其配置为基本或手动扩展。来自Scaling types and instance classes(表中Deadline 行):

    • Manual scaling 列中:

    请求可以无限期地运行。手动扩展的实例可以选择 处理 /_ah/start 并执行程序或脚本数小时 不返回 HTTP 响应代码。任务最长可运行 24 小时。

    • Basic scaling 列中:

    与手动缩放相同。

    通过相应模块的appengine-web.xml 文件完成的模块缩放配置在Scaling elements 中进行了描述:

    • <manual-scaling>:

    可选。该元素启用手动缩放 模块并设置模块的实例数。

    • <basic-scaling>:

    可选。元素设置实例数 对于一个模块。

    至于到模块的实际转换,请用Configuration Files(包括an example)和appengine-web.xml Syntax(参见moduleservice 配置)补充您指向的指南。

    关于appengine-application.xml,来自Configuration Files

    META-INF 目录有两个配置文件: appengine-application.xmlapplication.xml。这 appengine-application.xml 文件包含使用的一般信息 部署应用时的 App Engine 工具...

    ...

    请注意,虽然每个 appengine-web.xml 文件都必须包含 <application> 标签,您提供的名称将被忽略。的名字 该应用程序取自 <application> 中的标签 appengine-application.xml 文件。

    要将某个队列定向到某个服务/模块,请使用queue.xml 文件。来自Syntax

    • <target>(推队列):

    可选。命名模块/版本、前端版本或 后端,在其上执行所有排队的任务 排队。

    该字符串会在您的应用程序的域名之前添加 构造任务的 HTTP 请求。例如,如果您的应用 ID 是 my-app 并且您将目标设置为 my-version.my-service,即 URL 主机名将设置为 my-version.my-service.my-app.appspot.com

    如果未指定目标,则在同一版本上调用任务 他们被排队的应用程序。所以,如果你排队 来自默认应用程序版本的任务而不指定目标 在队列上,任务在默认应用程序版本中调用。 请注意,如果默认应用程序版本在此期间发生更改 任务入队和执行时间,然后任务 将在新的默认版本中运行。

    如果您将模块与 dispatch file 一起使用,则您的任务 HTTP 请求可能会被拦截并重新路由到另一个模块。

    【讨论】:

      【解决方案2】:

      模块和服务是一回事,它们类似于旧的后端(仍然有效,但已弃用)。

      有两种让模块工作的基本方法:

      • 创建一个 EAR 并部署它
      • 将服务独立部署为 WAR 文件(这可能是您现在对默认模块所做的)

      第二个选项可能更简单,因为只需更改 application-web.xml。您可以为每个模块创建一个 repo 或分支,或者只是一个更改目标模块的构建过程。

      现在你的 application-web.xml 可能是这样的:

      <application>@appId@</application>
      <version>@appVersion@</version>    
      <module>default</module>   
      

      改成这样的

      <application>@appId@</application>
      <version>@appVersion@</version>    
      <module>long-running-service</module>
      <instance-class>B1</instance-class>
      <manual-scaling>
          <instances>1</instances>
      </manual-scaling>
      

      您将队列本身配置为以queue.xml 中的特定模块为目标,请参阅here

      【讨论】:

      • 谢谢...!我遵循指南并成功地在应用引擎中创建了一个新服务。已经在 queue.xml 中添加了 ,但是有什么方法可以知道任务确实在后台执行,我有一个代码可以显示关于任务的不断更新,但是没有收到更新值在前端,可能是什么问题?另外,10分钟后,任务消失了,即使从任务队列中消失,任务是否还在后端实例上执行?
      • 您可以在云控制台中查看任务的重试状态,如果您想记录它,您也可以将重试计数作为请求的标头访问。您可以在云日志查看器中查看按服务细分的日志,以了解那里发生的情况。一个任务不应该消失,除非它成功或超过它的重试尝试。此外,当您的问题得到解决时,不要忘记接受最佳答案 - 它对每个人都有帮助。
      • 谢谢@Nick!这个答案让我对应用引擎中的服务和模块有了很大的了解,让我的概念更加清晰。