本文档介绍了如何为 Route Optimization API 请求配置超时和截止时间设置。未设置这些值或设置不正确可能会导致连接或回答质量问题。
您可以在请求正文中定义超时,在请求标头中定义截止时间。Route Optimization API 会在这些参数定义的时间限制内处理请求,并遵循最短时间值。
通过配置超时和截止时间,您可以通过以下方式管理处理时间:
- 增加处理时间:
- 解决高复杂度请求。
- 获得更高质量的回答。
- 缩短处理时间:
- 以比默认模型更快的速度解决复杂度较低的请求。
- 在更短的时间内解决请求,但获得的回答质量较低。
了解您的超时和截止时间需求
在配置超时和截止时间之前,请先查看本部分,以验证您是否了解端点和协议选择对这些设置的影响。
以下指南可帮助您确认是否使用了适合您目标的设置。
- 对于持续和重复的请求,以及受益于更长求解时间的复杂请求,请使用非阻塞端点。
- 对于小型请求和快速交付结果,请使用阻塞端点,接受质量权衡。
- 在日常工作流中使用 gRPC,尤其是对于生产应用。
- 使用 REST 进行测试、实验或一次性请求。
点击下面的按钮可查看图表,该图表可帮助您确定本文档的哪些部分与您的设置最相关。
设置 timeout 参数
在请求正文中设置 timeout 参数的值,以指定服务器在返回响应之前处理请求的最长时间。如果 API 在达到分配的时间上限之前找到最佳解决方案,则实际花费的时间可能比分配的时间短。
使用时长协议缓冲区设置 timeout 参数,该参数是以秒为单位的时长,范围为 1 秒到 1800 秒。使用 allowLargeDeadlineDespiteInterruptionRisk 可将此值最多增加到 3600 秒。
推荐的 timeout 值
下表根据请求复杂性以及配送和车辆数量列出了建议的 timeout 值。
| 配送和车辆数量 | 没有限制 | 时间窗口和负载限制宽松或路线较长 | 时间窗口紧迫、负载限制、复杂限制或路线过长 |
| 1 - 8 | 2 秒 | 2 秒 | 5 秒 |
| 9 - 32 | 5 秒 | 10 秒 | 20 秒 |
| 33 - 100 | 15 秒 | 30 秒 | 60 秒 |
| 101 - 1,000 | 45 秒 | 90 秒 | 180 秒 |
| 1,001 - 10,000 | 120 秒 | 360 秒 | 900s |
| 10,001 人(含)以上 | 60 秒 + 120 秒/1 万次配送 | 每 1 万次配送中 360 度的次数 | 每 1 万次配送 900 秒 |
设置截止日期
在请求标头中设置截止时间,以定义 Route Optimization API 处理请求所用的时间上限。以下各小节介绍了如何为 REST 和 gRPC 请求设置截止时间。
REST 请求
使用 REST 调用阻塞端点时,您可以将截止时间延长至默认的 60 秒以上,因为对于复杂请求,默认时间通常太短。即使您已在请求正文中指定了更长的时限,也必须执行此操作,因为默认时限会覆盖请求正文中设置的任何大于 60 秒的 timeout 值。
通过设置 X-Server-Timeout 请求标头,将截止时间延长到默认的 60 秒以上。与请求正文不同,标头的值是秒数,但没有“s”后缀。您可以为此标头设置的最大值与 timeout 参数的限制一致。
以下代码示例展示了将 X-Server-Timeout 设置为 1800 秒的 HTTP 标头。
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,以将超时和截止时间参数的值增加到最多 3600 秒。
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 指南。
包含 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)