הגדרת פסק זמן ומועדים

במאמר הזה מוסבר איך להגדיר את הגדרות הזמן הקצוב לתפוגה והמועד האחרון לבקשות API ל-Route Optimization API. אם לא מגדירים את הערכים האלה או מגדירים אותם בצורה שגויה, יכולות להיות בעיות בחיבור או באיכות התגובה.

מגדירים את הזמן הקצוב לתפוגה בגוף הבקשה ואת המועד האחרון בכותרת הבקשה. ‫Route Optimization API מעבד את הבקשה במסגרת מגבלת הזמן שמוגדרת בפרמטרים האלה, בהתאם לערך הזמן הקצר ביותר.

הגדרת פסק זמן ומועדים מאפשרת לכם לנהל את זמן העיבוד בדרכים הבאות:

  • להאריך את זמן העיבוד:
    • לפתור בקשות מורכבות מאוד.
    • לקבל תשובה באיכות גבוהה יותר.
  • קיצור זמן העיבוד:
    • לפתור בקשות פשוטות מהר יותר מאשר במודל ברירת המחדל.
    • לפתור בקשה בפחות זמן, אבל לקבל תשובה באיכות נמוכה יותר.

הערה: הפרמטרים של זמן קצוב לתפוגה ומועד אחרון חלים רק כש-solvingMode מוגדר לערך ברירת המחדל שלו, DEFAULT_SOLVE. אפשרויות אחרות של solvingMode, כמו VALIDATE_ONLY, DETECT_SOME_INFEASIBLE_SHIPMENTS או TRANSFORM_AND_RETURN_REQUEST, בדרך כלל לא דורשות התאמות של פסק זמן כי הן מהירות משמעותית.

הבנת הצרכים שלכם בנוגע לזמן קצוב לתפוגה ולמועד אחרון

כדאי לעיין בקטע הזה לפני שאתם מגדירים את הזמן הקצוב לתפוגה ואת המועדים האחרונים, כדי לוודא שאתם מבינים איך הבחירות של נקודת הקצה והפרוטוקול משפיעות על ההגדרות האלה.

ההנחיות הבאות יעזרו לכם לוודא שאתם משתמשים בהגדרה הנכונה בהתאם ליעדים שלכם.

  • כדאי להשתמש בנקודות קצה (endpoint) לא חוסמות לבקשות חוזרות ומתמשכות ולבקשות מורכבות שמועילות מזמני פתרון ארוכים יותר.
  • משתמשים בנקודות קצה חוסמות לבקשות קטנות ולקבלת תוצאות מהירות, תוך התפשרות על האיכות.
  • מומלץ להשתמש ב-gRPC: בתהליך העבודה היומיומי, במיוחד באפליקציות בסביבת ייצור.
  • משתמשים ב-REST לבדיקות, לניסויים או לבקשות חד-פעמיות.

כדי לראות דיאגרמה שיכולה לעזור לכם להבין אילו חלקים במאמרי עזרה אלה הכי רלוונטיים להגדרה שלכם, לחצו על הלחצן שלמטה.

פתיחת הדיאגרמה בכרטיסייה נפרדת

הגדרת הפרמטר timeout

מגדירים את הערך של הפרמטר timeout בגוף הבקשה כדי לציין את הזמן המקסימלי שהשרת יעבוד על בקשה לפני שיחזיר תגובה. יכול להיות שהזמן בפועל יהיה קצר יותר מהזמן שהוקצה, אם ה-API ימצא פתרון אופטימלי לפני שיגיע לזמן המקסימלי שהוקצה.

מגדירים את הפרמטר timeout באמצעות מאגר הפרוטוקול duration, שהוא משך זמן בשניות שיכול לנוע בין שנייה אחת ל-1,800 שניות. אפשר להגדיל את הערך הזה עד 3,600 שניות באמצעות allowLargeDeadlineDespiteInterruptionRisk.

בטבלה הבאה מפורטים ערכים מומלצים של 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 או יותר ‫60 שניות + 120 שניות לכל 10,000 משלוחים ‫360s לכל 10,000 משלוחים 900 שניות לכל 10,000 משלוחים

הגדרת המועד האחרון להגשה

כדי להגדיר את משך הזמן המקסימלי שבו ה-Route Optimization API מעבד בקשה, מגדירים את המועד האחרון בכותרת הבקשה. בסעיפי המשנה הבאים מוסבר איך להגדיר מועדים אחרונים לבקשות REST ו-gRPC.

בקשות REST

כשמשתמשים ב-REST כדי לקרוא לנקודת קצה חוסמת, אפשר להאריך את המועד האחרון מעבר לברירת המחדל של 60 שניות, שלעיתים קרובות קצרה מדי לבקשות מורכבות. חובה לעשות את זה גם אם כבר ציינתם מועד אחרון ארוך יותר בגוף הבקשה, כי מועד ברירת המחדל מבטל כל ערך של timeout שמוגדר בגוף הבקשה וארוך מ-60 שניות.

כדי להאריך את המועד האחרון מעבר ל-60 השניות שמוגדרות כברירת מחדל, צריך להגדיר את כותרת הבקשה X-Server-Timeout. בניגוד לגוף הבקשה, הערך של הכותרת הוא מספר השניות, אבל בלי הסיומת 's'. הערך המקסימלי שאפשר להגדיר לכותרת הזו תואם להגבלות של הפרמטר timeout.

בדוגמת הקוד הבאה מוצגת כותרת HTTP שבה הערך של X-Server-Timeout מוגדר ל-1,800 שניות.

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, לא צריך להגדיר מועד אחרון. מועד ההגשה הסופי שמוגדר כברירת מחדל כשמשתמשים בהם הוא 3,600 שניות, זמן הבקשה המקסימלי ל-API הזה. כדי להגדיר את זמן הפתרון, צריך להגדיר רק את המאפיין timeout בגוף הבקשה.

פרמטרים שמשפיעים על זמן קצוב לתפוגה ומועדים אחרונים

הפרמטרים הבאים משפיעים על אופן הפעולה של זמן קצוב לתפוגה ומועדים אחרונים:

  • אפשר לשלוט במועד האחרון המקסימלי לבקשה באמצעות allowLargeDeadlineDespiteInterruptionRisk.
  • הגדרת ההתנהגות של החיפוש, תוך איזון בין איכות הפתרון לבין זמן האחזור באמצעות searchMode.

allowLargeDeadlineDespiteInterruptionRisk

הפרמטר allowLargeDeadlineDespiteInterruptionRisk מגדיל את הזמן המקסימלי שמוקצב לבקשה ל-3,600 שניות. אם הפרמטר הזה לא מוגדר, הערך המקסימלי של הפרמטרים timeout ו-deadline הוא 1,800 שניות.

מגדירים את allowLargeDeadline DespiteInterruptionRisk ל-true כדי להגדיל את הערך של הפרמטרים timeout ו-deadline עד ל-3,600 שניות.

הערכים המותרים של allowLargeDeadline DespiteInterruptionRisk הם:

  • ‫true: מגדיל את הערך המקסימלי של הפרמטרים של הזמן הקצוב לתפוגה ומועד אחרון ל-3,600 שניות, תוך הכרה בסיכון להפרעה.
  • ‫false (ברירת המחדל): הערך המקסימלי של הפרמטרים timeout ו-deadline נשאר 1,800 שניות.

אם לדעתכם אתם צריכים פסק זמן ארוך יותר מ-3,600 שניות, פנו לנציג שלכם ב-Google.

searchMode

הפרמטר searchMode קובע איך הכלי לאופטימיזציה מחפש פתרונות, ומאפשר לכם לתת עדיפות לתגובה מהירה יותר (זמן אחזור קצר יותר) או לפתרון באיכות גבוהה יותר.

כשמגדירים עדיפות לאיכות גבוהה של הפתרון, לוקח לאופטימיזציה זמן רב למדי למצוא פתרון באיכות גבוהה. בבקשות ארוכות כאלה, כדאי להגדיר זמן קצוב ארוך יותר ולהשתמש בנקודות קצה שלא חוסמות, כדי למנוע בעיות בחיבור.

הערכים המותרים ל-searchMode הם:

  • ‫SEARCH_MODE_UNSPECIFIED (ברירת מחדל): מצב חיפוש לא מוגדר, שווה ערך ל-RETURN_FAST.
  • ‫RETURN_FAST: החיפוש נפסק אחרי שנמצא הפתרון הטוב הראשון.
  • ‫CONSUME_ALL_AVAILABLE_TIME: משקיע את כל הזמן הפנוי בחיפוש פתרונות טובים יותר. ממשק ה-API לא משתמש בכל הזמן הזמין אם הוא מוצא פתרון אופטימלי בשלב מוקדם.

הפעלת פינגים של keepalive

כששולחים בקשות לנקודות קצה חוסמות עם זמן קצוב לתפוגה של יותר מ-60 שניות, פינגים של keepalive עוזרים למנוע אובדן של החיבור בזמן שממתינים לתגובה. פינגים של Keepalive הם חבילות קטנות שנשלחות כדי לשמור על פעילות החיבור, וכדי לזהות ולמנוע אובדן חיבור.

מגדירים את הפרמטרים האלה בהתאם לפרוטוקול ה-API שבו משתמשים:

  • ‫REST: הגדרת keepalive ברמת חיבור ה-TCP.
  • ‫gRPC: מגדירים פינגים של שמירת חיבור בשקע ה-TCP הבסיסי או ישירות בפרוטוקול gRPC.

בקטעים הבאים מוסבר איך להגדיר פינגים של keepalive לשני הפרוטוקולים.

REST keepalive

הגדרת פינגים של keepalive כשמשתמשים ב-REST תלויה בספריית צד הלקוח ב-HTTP. ספריות לקוח וכלים, כמו curl, עשויים לספק אפשרויות תצורה ספציפיות או להפעיל פינגים באופן אוטומטי.

אם הספרייה חושפת את שקע ה-TCP הבסיסי, אפשר להגדיר פינגים של keepalive ישירות בשקע ה-TCP באמצעות אפשרויות כמו SO_KEEPALIVE. כדי לעשות את זה, משתמשים בפונקציות כמו setsockopt() או בפונקציות מקבילות.

הפונקציה הזו שמתארחת ב-GitHub מדגימה איך להגדיר את זה בצורה נכונה לצד הלקוח ב-HTTP המובנה של Python.

למידע נוסף על הודעות keep-alive ברמת ה-TCP, קראו את הסקירה הכללית של TLDP בנושא הודעות keep-alive או את מסמכי התיעוד של ספריית הלקוח של צד הלקוח ב-HTTP.

gRPC keepalive

פרוטוקול gRPC כולל מנגנון מובנה משלו לשמירת החיבור כחלק מהפרוטוקול. במדריך של gRPC בנושא keepalive מוסבר איך להגדיר את זה בשפת הלקוח.

הערה: שרתי gRPC עשויים לדחות לקוחות ששולחים יותר מדי פינגים. מומלץ להימנע מהגדרת תדירות גבוהה מדי של פינג keepalive.

בקשת gRPC לדוגמה עם keepalive

בדוגמה הבאה מוצג איך לשלוח בקשת optimizeTours באמצעות ספריית הלקוח של Python ופינגים של שמירת חיבור ברמת gRPC.

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)