設定逾時和期限

本文說明如何設定 Route Optimization API 要求的逾時和期限設定。如果未設定或設定錯誤,可能會導致連線或回應品質問題。

您可以在要求主體中定義逾時,並在要求標頭中定義期限。Route Optimization API 會在這些參數定義的時間限制內處理要求,並以最短時間值為準。

設定逾時和期限後,您就能透過下列方式管理處理時間:

  • 增加處理時間:
    • 解決高複雜度的要求。
    • 取得更高品質的回覆。
  • 縮短處理時間:
    • 比預設模型更快解決複雜度較低的要求。
    • 縮短解決要求所需的時間,但回覆品質較低。

瞭解逾時和期限需求

設定逾時和期限前,請先詳閱本節,確認您瞭解端點和通訊協定選擇對這些設定的影響。

請參考下列規範,確認設定是否符合目標。

  • 對於持續和重複的要求,以及需要較長解決時間的複雜要求,請使用非阻塞端點。
  • 使用封鎖端點處理小型要求並快速提供結果,接受品質折衷。
  • 在日常工作流程中使用 gRPC,尤其是正式版應用程式。
  • REST 適用於測試、實驗或一次性要求。

請點選下方按鈕查看圖表,判斷本文件哪些部分與您的設定最相關。

在另一個分頁中開啟圖表

設定 timeout 參數

在要求主體中設定 timeout 參數的值,指定伺服器處理要求並傳回回應的時間上限。如果 API 在達到分配時間上限前找到最佳解決方案,實際花費的時間可能會比分配時間短。

使用時間長度通訊協定緩衝區設定 timeout 參數,時間長度以秒為單位,範圍為 1 秒到 1800 秒。使用 allowLargeDeadlineDespiteInterruptionRisk 增加這個值,最多可達 3600 秒。

下表根據要求複雜度、運送數量和車輛數量,列出建議的 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 秒 360s 900s
10,001 人以上 每 1 萬次出貨 60 秒 + 120 秒 每 1 萬件貨物中 360 度的數量 每 1 萬次出貨 900 秒

設定期限

在要求標頭中設定期限,定義 Route Optimization API 處理要求的時間上限。以下子節說明如何設定 REST 和 gRPC 要求的期限。

REST 要求

使用 REST 呼叫封鎖端點時,您可以將期限延長至預設的 60 秒以上,因為 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 的要求時間上限。如要設定求解時間,請只在要求主體中設定 timeout 屬性。

影響逾時和期限的參數

下列參數會影響逾時和期限的運作方式:

  • 使用 allowLargeDeadlineDespiteInterruptionRisk 控制要求期限上限。
  • 定義搜尋行為,並使用 searchMode 兼顧解決方案品質和延遲時間。

allowLargeDeadlineDespiteInterruptionRisk

allowLargeDeadlineDespiteInterruptionRisk 參數會將要求期限上限提高至 3600 秒。如未設定這項參數,逾時和期限參數的最大值均為 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 連線層級設定 Keep-Alive。
  • gRPC:在基礎 TCP 通訊端或直接在 gRPC 通訊協定中設定 keepalive ping。

以下各節說明如何為這兩種通訊協定設定 Keepalive ping。

REST 保持連線

使用 REST 時,設定持續連線偵測 (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 範例要求

以下範例說明如何使用 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)