有没有办法使用 App Engine Java 运行时动态设置任务的目标?

Luk*_*ncl 5 java google-app-engine task-queue google-cloud-platform

使用 App Engine Python 运行时对后台任务进行排队时,您可以为队列指定一个目标,该目标将发送要在特定服务、版本或实例上运行的任务:

task = taskqueue.add(
    url='/update_counter',
    target='worker',
    params={'amount': amount})
Run Code Online (Sandbox Code Playgroud)

有没有办法在 Java 中做到这一点?该文档提到了该target参数,但没有显示如何使用它的示例。该Queue.add方法没有针对 的选项target。这个TaskOptions类也没有任何看起来像target

这个问题记录了如何使用target,但答案是在queue.xml. 我想在运行时选择目标,比如 Python。

Tux*_*ude 5

TL;DR - 可能有一种方法可以根据文档的早期版本来执行此操作,但最新版本的文档中未对此进行描述。

基于最新文档的方法

根据有关推送队列最新文档(就像您已经提到的那样),您可以在queue.xml每个队列中配置目标模块和版本。如果指定,则将任务请求发送到指定的目标。正如您已经描述的那样,这是一个静态配置,并不能真正回答您的问题(描述只是为了完整性)。

<?xml version="1.0" encoding="UTF-8"?>
  <queue-entries>
    <queue>
      <name>queue-blue</name>
      <target>v2.task-module</target>
    </queue>
    <queue>
      <name>queue-red</name>
      <rate>1/s</rate>
    </queue>
  </queue-entries>
Run Code Online (Sandbox Code Playgroud)

创建任务和指定工作服务文档中,它描述了为任务选择的目标,但没有清楚地描述如何指定它。

当一个任务从它的队列中弹出时,任务队列服务将它发送到一个工作服务。每个任务都有一个目标和一个 url,它们决定了最终将执行任务的服务和处理程序。

target

目标指定将接收 HTTP 请求以执行任务的服务。它是一个字符串,以任何一种规范形式指定服务/版本/实例。最常用的有:

service
version.service
instance.version.service
Run Code Online (Sandbox Code Playgroud)

目标字符串被添加到您的应用程序的域名之前。可以通过三种方式为任务设置目标:

  • 在构造任务时明确声明目标。
  • 在 queue.xml 中定义队列时包括目标指令,如上面 queue-blue 的定义。添加到具有目标的队列的所有任务都将使用该目标,即使在构建时为任务分配了不同的目标。
  • 如果根据前两种方法中的任何一种都没有指定目标,则任务的目标是将其加入队列的服务的版本。请注意,如果您以这种方式将任务从默认服务和版本中排入队列,并且在任务执行之前默认版本发生变化,它将在新的默认版本中运行。

url

url在所述目标服务的处理程序,将执行该任务中选择一个。

url应与目标服务的处理程序URL模式之一。如果任务的方法是GET或 ,则 url 可以包含查询参数 PULL。如果未指定 url,则使用默认 URL /_ah/queue/[QUEUE_NAME],其中[QUEUE_NAME]是任务队列的名称。

根据上述文档,如果您查看TaskOptions.Builder,则无法指定任务的目标。这可能表明缺少有关如何指定目标的文档,或者只是在将任务添加到队列时无法再动态指定目标。查看下面基于早期文档描述的方法。

基于早期文档的方法

免责声明:我在这里提到的内容似乎基于过时的信息(我引用了下面的来源),因此可能无法按预期工作和/或在未来中断。

您可以使用Host标头指定将获取请求的模块、版本和实例信息。

要指定模块和版本,您可以执行以下操作:

Queue queue = QueueFactory.getQueue("QUEUE_NAME");
    queue.add(TaskOptions.Builder
            .withUrl("/url/path")
            .param("key", "PARAM")
            .header("Host",
                    ModulesServiceFactory.getModulesService().getVersionHostname("MODULE_NAME", "VERSION")));
Run Code Online (Sandbox Code Playgroud)

要指定实例,您可以执行以下操作:

Queue queue = QueueFactory.getQueue("QUEUE_NAME");
    queue.add(TaskOptions.Builder
            .withUrl("/url/path")
            .param("key", "PARAM")
            .header("Host",
                    ModulesServiceFactory.getModulesService().getInstanceHostname("MODULE_NAME", "VERSION", "INSTANCE_NAME"));
Run Code Online (Sandbox Code Playgroud)

我在当前版本的 App Engine 文档中找不到此信息,但使用 Wayback 机器,我从 2016 年 1 月 1 日早期版本的文档中找到了此信息,该文档描述了推送任务的执行。在这个github issue 中,它也在不同的上下文中进行了讨论。

推送任务执行

App Engine 通过向您的应用程序发送 HTTP POST 请求来执行推送任务。将编程异步回调指定为 HTTP 请求有时称为 Web 钩子。网络钩子模型可以实现高效的并行处理。

任务的 URL 确定任务的处理程序和运行处理程序的模块。

处理程序由 URL 的路径部分(主机名后面的正斜杠分隔字符串)确定,该部分由您在调用 Queue.add() 方法时包含的 TaskOptions 中的 url 参数指定。该 url 必须相对于您的应用程序的根目录并且是本地的。

处理程序运行的模块和版本由以下因素决定:

  • 您在调用 Queue.add() 方法时包含的 TaskOptions 中的“Host”标头参数。
  • queue.xml 或 queue.yaml 文件中的目标指令。

如果您不指定这些参数中的任何一个,则该任务将在其排队时所在的同一模块/版本中运行,并遵守以下规则:

  • 如果应用程序的默认版本将任务排入队列,则该任务将在默认版本上运行。请注意,如果应用程序将任务排入队列,并且在任务实际运行之前更改了默认版本,则任务将在新的默认版本中执行。

  • 如果非默认版本将任务排入队列,则该任务将始终在同一版本上运行。

注意:如果您将模块与调度文件一起使用,则任务的 URL 可能会被拦截并重新路由到另一个模块。

推送任务运行所在的命名空间是在将任务添加到队列时确定的。默认情况下,任务将在创建任务的进程的当前命名空间中运行。您可以通过在将任务添加到队列之前显式设置命名空间来覆盖此行为,如多租户页面所述。