逾時和期限

本文說明如何為 Route Optimization API 要求設定逾時和截止時間。如果未設定這些值或設定錯誤,可能會導致連線或回應品質問題。

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

設定逾時和期限可讓您透過下列方式管理處理時間:

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

注意:只有在 solvingMode 設為預設值 DEFAULT_SOLVE 時,逾時和截止期限參數才會生效。其他 solvingMode 選項 (例如 VALIDATE_ONLYDETECT_SOME_INFEASIBLE_SHIPMENTSTRANSFORM_AND_RETURN_REQUEST) 通常不需要調整逾時,因為速度明顯較快。

瞭解逾時和截止期限需求

請先詳閱本節內容,再設定逾時和截止時間,確認您瞭解端點和通訊協定選擇對這些設定的影響。

請參考下列規範,確認您是否採用適合目標的設定。

  • 如要連續重複提出要求,以及處理需要較長解決時間的複雜要求,請使用非封鎖端點
  • 對於小型要求和快速傳送結果,請使用封鎖端點,並接受品質上的取捨。
  • 使用 gRPC:適用於日常工作流程,特別是正式版應用程式。
  • 使用 REST 進行測試、實驗或一次性要求。

按一下下方按鈕,查看有助於判斷文件哪些部分與設定最相關的圖表。

在另一個分頁中開啟圖表

設定 timeout 參數

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

使用 duration 通訊協定緩衝區設定 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 秒 360 秒 900 秒
10,001 人以上 每 1 萬件出貨商品 60 秒 + 120 秒 每 1 萬件出貨的 360 秒 每 1 萬件出貨商品 900 秒

設定期限

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

REST 要求

使用 REST 呼叫封鎖端點時,您可以將期限延長至超過預設的 60 秒,因為複雜的要求通常需要較長的時間。即使您已在要求主體中指定較長的期限,也必須這麼做,因為預設期限會覆寫要求主體中大於 60 秒的任何 timeout 值。

如要將期限延長至預設的 60 秒以上,請設定 X-Server-Timeout 要求標頭。與要求主體不同,標頭的值是以秒為單位,但沒有「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 時,您不需要設定期限。使用這些 API 時,預設期限為 3600 秒,也就是此 API 的要求時間上限。只要在要求主體中設定逾時屬性,即可設定解決時間。

影響逾時和期限的參數

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

  • 使用 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 提早找到最佳解決方案,就不會用盡所有可用時間。

啟用存活 Ping

當您向封鎖端點發出要求,且逾時時間超過 60 秒時,保持運作 Ping 可協助您在等待回應時避免連線中斷。Keepalive ping 是為維持連線活動而傳送的小型封包,可偵測並防止連線中斷。

請根據您使用的 API 通訊協定設定這些參數:

  • REST:在 TCP 連線層級設定存留時間。
  • gRPC:在基礎 TCP Socket 或 gRPC 通訊協定中直接設定 Keepalive Ping。

下列各節說明如何為這兩種通訊協定設定存活偵測 Ping。

REST 保持運作

使用 REST 時,設定存留連線 Ping 取決於您的 HTTP 用戶端程式庫。用戶端程式庫和工具 (例如 curl) 可能會提供特定設定選項,或自動啟用 Ping。

如果程式庫公開基礎 TCP Socket,您可以使用 SO_KEEPALIVE 等選項,直接在 TCP Socket 上設定存留信號。方法是使用 setsockopt() 或對等函式。

這項函式託管於 GitHub,示範如何為 Python 內建 HTTP 用戶端正確設定這項功能。

如要進一步瞭解 TCP 層級的保持運作狀態,請參閱 TLDP 保持運作狀態總覽或 HTTP 用戶端程式庫說明文件。

gRPC 保持運作

gRPC 提供內建的連線存續機制,做為通訊協定的一部分。如需瞭解如何在用戶端語言中設定這項功能,請參閱 gRPC 存留連線指南

注意:如果用戶端傳送過多 Ping,gRPC 伺服器可能會拒絕用戶端。避免將連線存續信號的傳送頻率設得過高。

使用 Keepalive 的 gRPC 範例要求

以下範例說明如何使用 Python 用戶端程式庫和 gRPC 層級的存留信號,發出 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)