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

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

בטבלה הבאה מפורטים ערכים מומלצים של timeout על סמך מורכבות הבקשה ומספר המשלוחים וכלי הרכב.

מספר המשלוחים וכלי הרכב ללא אילוצים חלונות זמן רחבים ומגבלות טעינה או מסלולים ארוכים חלונות זמן קצרים, מגבלות על העומס, מגבלות מורכבות או מסלולים ארוכים מאוד
1 - 8 ‫2s ‫2s ‫5 שניות
‫9 - 32 ‫5 שניות 10 שנ' 20 שנ'
‫33-100 15 שנ' ‎30ש 60 שנ'
‫101 עד 1,000 ‫45 שניות שנות ה-90 180s
‫1,001 עד 10,000 ‫120s ‫360s ‫900s
‫10,001 או יותר ‫60 שניות + 120 שניות לכל 10,000 משלוחים סביבות 360 לכל 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 הזה. כדי להגדיר את זמן הפתרון, צריך להגדיר רק את מאפיין הזמן הקצוב לתפוגה בגוף הבקשה.

פרמטרים שמשפיעים על פסק זמן ועל מועדים

הפרמטרים הבאים משפיעים על הפעולה של פסק זמן ושל מועד אחרון:

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

allowLargeDeadlineDespiteInterruptionRisk

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

מגדירים את allowLargeDeadline DespiteInterruptionRisk ל-true כדי להגדיל את הערך של הפרמטרים של הזמן הקצוב לתפוגה ושל תאריך היעד ל-3,600 שניות.

הערכים המותרים למאפיין allowLargeDeadline DespiteInterruptionRisk הם:

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

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

searchMode

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

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

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

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

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

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

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

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

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

הודעת keep-alive של REST

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

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

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

פרטים נוספים על הודעות keep-alive ברמת TCP זמינים בסקירה הכללית של TLDP keepalive או במסמכי התיעוד של ספריית הלקוח של HTTP.

הודעת keep-alive ב-gRPC

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

הערה: שרתי 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)