超时和截止期限

本文档介绍了如何为路线优化 API 请求配置超时和截止时间设置。不设置这些值或设置不正确可能会导致连接或响应质量问题。

您可以在请求正文中定义超时时间,在请求标头中定义截止时间。路线优化 API 会在这些参数定义的时间限制内处理请求,并遵循最短的时间值。

通过配置超时和截止时间,您可以按以下方式管理处理时间:

  • 增加处理时间
    • 解决高复杂度的请求。
    • 获得更优质的回答。
  • 缩短处理时间
    • 以比默认速度更快的速度解决低复杂度的请求。
    • 在更短的时间内解决请求,但获得较低质量的回答。

注意:只有当 solvingMode 设置为默认值 DEFAULT_SOLVE 时,超时和截止时间参数才适用。其他 solvingMode 选项(例如 VALIDATE_ONLYDETECT_SOME_INFEASIBLE_SHIPMENTSTRANSFORM_AND_RETURN_REQUEST)通常不需要调整超时时间,因为它们的速度明显更快。

了解您的超时和截止期限需求

在配置超时和截止时间之前,请先查看本部分,以确保您了解端点和协议选择对这些设置的影响。

以下指南可帮助您确认自己是否使用了适合目标的效果衡量设置。

  • 对于持续且重复的请求,以及需要较长求解时间的复杂请求,请使用非阻塞端点
  • 对于小型请求和快速交付结果,请使用阻塞端点,但要接受质量上的权衡。
  • 在日常工作流程中,尤其是对于生产应用,请使用 gRPC
  • 使用 REST 进行测试、实验或一次性请求。

点击下方的按钮可查看一张图表,该图表可帮助您确定本文档的哪些部分与您的设置最相关。

在单独的标签页中打开图表

设置 timeout 参数

在请求正文中设置 timeout 参数的值,以指定服务器在返回响应之前处理请求的最长时间。如果 API 在达到分配的最长时间之前找到了最佳解决方案,则实际花费的时间可能会短于分配的时间。

使用时长协议缓冲区设置 timeout 参数,该参数是以秒为单位的时长,范围可以从 1 秒到 1800 秒不等。使用 allowLargeDeadlineDespiteInterruptionRisk 将此值增加到最多 3,600 秒。

下表列出了建议的 timeout 值,具体取决于请求复杂程度以及货件和车辆的数量。

货件和车辆数量 无限制 时间窗口和装载量限制宽松或路线较长 时间窗口较短、存在载重限制、存在复杂限制条件或路线很长
1 - 8 2s 2s 5 秒
9 - 32 5 秒 10 秒 20 秒
33 - 100 15 秒 30 秒 60 秒
101 - 1,000 45 秒 90 秒 180 秒
1,001 - 10,000 120 秒 360s 900 秒
10,001 人或更多 每 1 万件货件 60 秒 + 120 秒 每 1 万件货件的 360 度全景照片数量 每 1 万件货件的 900s 数量

设置截止时间

在请求标头中设置截止时间,以定义路线优化 API 处理请求所用的最长时间。以下各小节介绍了如何为 REST 和 gRPC 请求设置截止时间。

REST 请求

使用 REST 调用阻塞端点时,您可以将截止时间延长到超出默认的 60 秒,这对于复杂请求来说通常太短。即使您已在请求正文中指定了更长的时限,也必须这样做,因为默认时限会替换请求正文中设置的任何大于 60 秒的 timeout 值。

通过设置 X-Server-Timeout 请求标头,将截止时间延长到默认的 60 秒以上。与请求正文不同,标头的值是秒数,但不带“s”后缀。您可以为此标头设置的最大值与 timeout 参数的限制保持一致。

以下代码示例展示了一个 HTTP 标头,其中 X-Server-Timeout 设置为 1800 秒。

curl -X POST 'https://routeoptimization.googleapis.com/v1/projects/:optimizeTours' \
-H "Content-Type: application/json" \
-H "X-Server-Timeout: 1800" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data @- << EOM
{
  "model": {
    ...
  }
}
EOM

客户端库和 gRPC 请求

使用客户端库或 gRPC 时,无需配置截止时间。使用这些方法时的默认截止时间为 3600 秒,即此 API 的最长请求时间。仅通过在请求正文中设置超时属性来配置求解时间。

影响超时和截止时间的参数

以下参数会影响超时和截止时间的运作方式:

  • 使用 allowLargeDeadlineDespiteInterruptionRisk 控制请求截止时限上限。
  • 使用 searchMode 定义搜索行为,在解决方案质量与延迟之间取得平衡。

allowLargeDeadlineDespiteInterruptionRisk

allowLargeDeadlineDespiteInterruptionRisk 参数会将最长请求截止期限增加到 3,600 秒。如果未设置此参数,则超时和截止时间参数的最大值均为 1800 秒。

allowLargeDeadline DespiteInterruptionRisk 设置为 true,以将超时和截止时间参数的值增加到最多 3,600 秒。

allowLargeDeadline DespiteInterruptionRisk 的允许值如下:

  • true:将超时和截止时间参数的最大值增加到 3600 秒,同时确认中断风险。
  • false(默认值):将超时和截止时间参数的最大值保持为 1800 秒。

如果您认为需要将超时时间设置为超过 3600 秒,请与您的 Google 代表联系。

searchMode

searchMode 参数用于控制优化器搜索解决方案的方式,以便您可以优先考虑更快的响应速度(更低的延迟时间)或更高质量的解决方案。

如果您优先考虑更高的解决方案质量,优化器会花费相当长的时间来寻找高质量的解决方案。对于这些时间较长的请求,请考虑设置更长的超时时间并使用非阻塞端点,以避免连接问题。

searchMode 的允许值如下:

  • SEARCH_MODE_UNSPECIFIED(默认):未指定的搜索模式,相当于 RETURN_FAST
  • RETURN_FAST:在找到第一个合适的解决方案后停止搜索。
  • CONSUME_ALL_AVAILABLE_TIME:花费所有可用时间来寻找更好的解决方案。如果 API 提前找到了最佳解决方案,就不会使用所有可用时间。

启用 keepalive ping

当您向阻塞端点发出请求且超时时间超过 60 秒时,keepalive ping 可帮助防止在等待响应时丢失连接。Keepalive ping 是为保持连接活动状态而发送的小数据包,用于检测和防止连接丢失。

根据您使用的 API 协议配置这些参数:

  • REST:在 TCP 连接级别配置 keepalive。
  • gRPC:在底层 TCP 套接字或直接在 gRPC 协议中配置 keepalive ping。

以下部分介绍了如何为这两种协议设置 keepalive ping。

REST Keepalive

使用 REST 时配置 keepalive ping 取决于您的 HTTP 客户端库。客户端库和工具(例如 curl)可能会提供特定的配置选项或自动启用 ping。

如果您的库公开了底层 TCP 套接字,您可以使用 SO_KEEPALIVE 等选项直接在 TCP 套接字上配置 keepalive ping。为此,请使用 setsockopt() 或其等效函数。

托管在 GitHub 上的函数演示了如何为 Python 内置 HTTP 客户端正确设置此功能。

如需详细了解 TCP 级 keepalive,请参阅 TLDP keepalive 概览或 HTTP 客户端库文档。

gRPC Keepalive

gRPC 在协议中提供了自己的内置 keepalive 机制。如需了解如何在客户端语言中设置此功能,请参阅 gRPC keepalive 指南

注意:gRPC 服务器可能会拒绝发送过多 ping 的客户端。避免将 keepalive ping 频率设置得过高。

包含 keepalive 的 gRPC 示例请求

以下示例展示了如何使用 Python 客户端库和 gRPC 级 keepalive ping 发出 optimizeTours 请求。

from google.maps import routeoptimization_v1 as ro
from google.maps.routeoptimization_v1.services.route_optimization.transports import grpc as grpc_transport
import sys

_REQUEST_TIMEOUT_SECONDS = 1800
_KEEPALIVE_PING_SECONDS = 30

def create_channel(*args, **kwargs):
  raw_options = kwargs.pop("options", ())
  options = dict(raw_options)
  options["grpc.keepalive_time_ms"] = _KEEPALIVE_PING_SECONDS * 1000
  options["grpc.keepalive_timeout_ms"] = 5000
  # Allow any number of pings between the request and the response.
  options["grpc.http2.max_pings_without_data"] = 0
  print(f"Using options: {options}", file=sys.stderr)
  return grpc_transport.RouteOptimizationGrpcTransport.create_channel(
      *args,
      options=list(options.items()),
      **kwargs,
  )

def create_grpc_transport(*args, **kwargs):
  if "channel" in kwargs:
    raise ValueError(
        "`channel` is overridden by this function, and must not be provided."
    )
  return grpc_transport.RouteOptimizationGrpcTransport(
      *args,
      channel=create_channel,
      **kwargs,
  )

def run_optimize_tours(request):
  client = ro.RouteOptimizationClient(transport=create_grpc_transport)
  return client.optimize_tours(request, timeout=_REQUEST_TIMEOUT_SECONDS)