סקירה כללית של פתרון בעיות
בדף הזה מופיע מידע כללי על פתרון בעיות ב-API Gateway.
אי אפשר להריץ פקודות של "gcloud api-gateway"
כדי להריץ את הפקודות של gcloud api-gateway ..., צריך לעדכן את Google Cloud CLI ולהפעיל את שירותי Google הנדרשים.
למידע נוסף, קראו את המאמר הגדרת סביבת הפיתוח.
הפקודה "gcloud api-gateway api-configs create" מציינת שחשבון השירות לא קיים
אם מריצים את הפקודה gcloud api-gateway api-configs create ... ומתקבלת שגיאה בפורמט הבא:
ERROR: (gcloud.api-gateway.api-configs.create) FAILED_PRECONDITION: Service Account "projects/-/serviceAccounts/service_account_email" does not exist
מריצים מחדש את הפקודה, אבל הפעם כוללים את האפשרות --backend-auth-service-account כדי לציין במפורש את כתובת האימייל של חשבון השירות שבו רוצים להשתמש:
gcloud api-gateway api-configs create CONFIG_ID \ --api=API_ID --openapi-spec=API_DEFINITION \ --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL
חשוב לוודא שכבר הקציתם את ההרשאות הנדרשות לחשבון השירות, כמו שמתואר במאמר הגדרת סביבת הפיתוח.
איך לזהות את המקור של תגובות השגיאה ב-API
אם בקשות ל-API שנפרס גורמות לשגיאה (קודי סטטוס של HTTP 400 עד 599), יכול להיות שלא יהיה ברור מהתגובה עצמה אם מקור השגיאה הוא בשער או בבק-אנד.
כדי לבדוק את זה:
נכנסים לדף Logs Explorer ובוחרים את הפרויקט.
מסננים למשאב השער הרלוונטי באמצעות שאילתת היומן הבאה:
resource.type="apigateway.googleapis.com/Gateway" resource.labels.gateway_id="GATEWAY_ID" resource.labels.location="GCP_REGION"
כאשר:
- GATEWAY_ID מציין את שם השער.
- GCP_REGION הוא האזור ( Google Cloud ) של השער שנפרס.
מוצאים את הרשומה ביומן שתואמת לתגובת השגיאה ב-HTTP שרוצים לבדוק. לדוגמה, סינון לפי
httpRequest.status.בודקים את התוכן של השדה
jsonPayload.responseDetails.
אם הערך של השדה jsonPayload.responseDetails הוא "via_upstream", מקור השגיאה הוא בקצה העורפי, ותצטרכו לפתור את הבעיה ישירות בקצה העורפי. אם מופיע ערך אחר, מקור השגיאה הוא בשער. במקרה כזה, אפשר להיעזר בטיפים לפתרון בעיות שמופיעים בקטעים הבאים במסמך הזה.
בקשת ה-API מחזירה שגיאת HTTP 403
אם בקשה ל-API שנפרס מחזירה שגיאת HTTP 403 ללקוח ה-API, המשמעות היא שכתובת ה-URL המבוקשת תקינה אבל הגישה אסורה מסיבה כלשהי.
ל-API שנפרס יש את ההרשאות שמשויכות לתפקידים שניתנו לחשבון השירות שבו השתמשתם כשיצרתם את הגדרת ה-API. בדרך כלל, הסיבה לשגיאת HTTP 403 היא שלחשבון השירות אין את ההרשאות הנדרשות כדי לגשת לשירות לקצה העורפי.
אם הגדרתם את ה-API ואת השירות לקצה העורפי באותו פרויקט בענן ב-Google Cloud, ודאו שלחשבון השירות הוקצה התפקיד Editor או התפקיד שנדרש כדי לגשת לשירות לקצה העורפי. לדוגמה, אם שירות הקצה העורפי מיושם באמצעות פונקציות Cloud Run, ודאו שלחשבון השירות מוקצה התפקיד Cloud Function Invoker.
בקשת ה-API מחזירה שגיאת HTTP מסוג 401 או 500
אם בקשה ל-API שנפרס מחזירה ללקוח ה-API שגיאת HTTP 401 או 500, יכול להיות שיש בעיה בשימוש בחשבון השירות שבו השתמשתם כשיצרתם את הגדרת ה-API כדי לשלוח קריאה לשירות לקצה העורפי.
ל-API שנפרס יש את ההרשאות שמשויכות לתפקידים שניתנו לחשבון השירות שבו השתמשתם כשיצרתם את הגדרת ה-API. חשבון השירות נבדק כדי לוודא שהוא קיים ושה-API Gateway יכול להשתמש בו כשה-API נפרס.
אם חשבון השירות נמחק או מושבת אחרי פריסת השער, יכול להיות שיקרו הדברים הבאים:
מיד אחרי שחשבון השירות נמחק או מושבת, יכול להיות שיופיעו תגובות HTTP 401 ביומני השער. אם השדה
jsonPayload.responseDetailsמוגדר כ-"via_upstream"ב-jsonPayloadשל הרשומה ביומן, סימן שהשגיאה נגרמה בגלל מחיקה או השבתה של חשבון השירות.יכול להיות גם שתראו שגיאת HTTP
500בלי רשומה תואמת ביומנים של API Gateway. אם אין בקשות לשער מיד אחרי שחשבון השירות נמחק או הושבת, יכול להיות שלא תראו את התגובות מסוג HTTP 401, אבל שגיאות ה-HTTP500בלי יומני שער API תואמים מצביעות על כך שחשבון השירות של השער כבר לא פעיל.
אם הקצה העורפי של הבקשה שנכשלה הוא ממשק API אחר של Google Cloud (כמו bigquery.googleapis.com), תגובות HTTP 401 יופיעו ביומני השער, והשדה jsonPayload.responseDetails יוגדר כ-"via_upstream". הסיבה לכך היא ש-API Gateway מבצע אימות לקצוות עורפיים באמצעות טוקן מזהה, ואילו ממשקי API אחרים של Google Cloud דורשים טוקן גישה.
בקשת API מחזירה שגיאת HTTP 500 עבור שיטה עם מכסה
אם מופיעה השגיאה הבאה, סימן שהשער לא הצליח להקצות מכסה לבקשה:
HTTP/2 500 {"code":500,"message":"Failed to call Service Control Quota."}
השגיאה הזו מתרחשת בדרך כלל כשקוראים ל-method שמוגדרת לו מכסה, אבל מדדי המכסה כבר לא קיימים ב-API. בשער gRPC, אותו כשל מוחזר כקוד הסטטוס Internal של gRPC.
אישור הסיבה ביומני השער
נכנסים לדף Logs Explorer ובוחרים את הפרויקט.
מריצים את שאילתת היומן הבאה:
resource.type="apigateway.googleapis.com/Gateway" resource.labels.gateway_id="GATEWAY_ID" jsonPayload.responseDetails="service_control_quota_error" httpRequest.status=500
כאשר GATEWAY_ID מציין את שם השער.
השאילתה מסננת לפי קוד הסטטוס וגם לפי
jsonPayload.responseDetails, כי API Gateway משתמש באותו ערך שלresponseDetailsלכל דחייה של מכסה. בקשה שחרגה מהמכסה שלה באופן לגיטימי מפיקה את אותו ערך עםhttpRequest.statusשל429.בודקים את השדות
jsonPayload.apiConfigו-jsonPayload.apiMethodבכל רשומה תואמת. הם מזהים את הגדרת ה-API ואת ה-method שהגדרת המכסה שלה לא תקינה.
למה הגדרת המכסה של ה-API יכולה להיות לא תקינה
אתם מגדירים את המדדים והמגבלות של המכסות בהגדרות ה-API, אבל API Gateway מחיל אותם על ה-API כולו. בכל פעם שיוצרים הגדרת API, המדדים והמגבלות שמוצהרים בה מחליפים את אלה שהוצהרו בהגדרות ה-API הקודמות של ה-API. רק הערכים מהגדרת ה-API שנוצרה לאחרונה נאכפים.
לעומת זאת, המדדים שכל שיטה צורכת מוגדרים בהגדרות ה-API שהשער משרת. אם בשער פועלת הגדרת API ישנה יותר, הוא מבקש מ-Service Control להקצות מכסת הקצאה למדד שקיים בהגדרה שלו, אבל יכול להיות שהוא לא קיים ב-API. אם המדד לא קיים, קריאת ההקצאה נכשלת והשער דוחה את הבקשה.
לדוגמה, ברצף הבא השער הראשון נשאר פגום:
- אתם יוצרים את הגדרת ה-API
config-v1, שמצהירה על המדדquota-metric-v1, ופורסים אותה ב-gateway-1. - אתם יוצרים את הגדרת ה-API
config-v2לאותו API, שמצהיר על המדדquota-metric-v2, ופורסים אותו ב-gateway-2.
gateway-2 פועל, אבל בקשות למתודות של gateway-1 שמוגבלות במכסות מתחילות להיכשל, כי quota-metric-v1 כבר לא מוגדר ל-API.
השינויים הבאים יכולים לגרום לשגיאות בכל שער שעדיין פרוס עם הגדרת API קודמת:
- שינוי שם של מדד או הסרה שלו.
- שינוי המדד שעליו חלה מגבלת המכסה.
- שינוי המדד שמופיע בעלויות המכסות לכל שיטה (
x-google-quotaלמסמכי OpenAPI אוquota.metric_rulesלהגדרות שירות של gRPC).
שינוי רק של ערך המגבלה לא גורם לשגיאות. עם זאת, מכיוון שהמגבלות חלות גם ברמת ה-API, הערך החדש נאכף בכל שער של אותו API, כולל שערים שנפרסו עם הגדרת API קודמת.
השוואה בין הגדרות המכסות שנפרסו
מציגים את השערים ואת הגדרת ה-API שכל אחד מהם משרת:
gcloud api-gateway gateways list \ --format="table(name.basename(),apiConfig)"
מציגים את רשימת הגדרות ה-API של ה-API המושפע, בסדר יורד לפי תאריך היצירה:
gcloud api-gateway api-configs list --api=API_ID \ --format="table(name.basename(),createTime:sort=1:reverse)"
הרשומה הראשונה היא הגדרת ה-API שמדדי המכסות והמגבלות שלה נאכפים על ה-API כולו. ממיינים באמצעות הדגל
--formatכמו שמוצג: הפקודה הזו לא תומכת בדגל--sort-by, והיא לא מחזירה הגדרות API בסדר צפוי.כדי להציג את הגדרת ה-API שממנה נוצרה הגדרת ה-API:
gcloud api-gateway api-configs describe CONFIG_ID --api=API_ID \ --view=FULL --format="value(openapiDocuments[0].document.contents)" \ | tr '_-' '/+' | base64 --decode
צריך להשתמש בפקודה
trכי השדהcontentsמקודד ב-base64url, ו-base64 --decodeלא יכול לקרוא אותו ישירות.ב-gRPC API, הגדרת המכסה נמצאת בהגדרת השירות ולא במסמך OpenAPI, לכן צריך להחליף את
openapiDocuments[0].document.contentsב-managedServiceConfigs[0].contents.מריצים את הפקודה שבשלב 3 בשביל הגדרת ה-API שבראש הרשימה משלב 2, ואז בשביל כל אחת מהגדרות ה-API האחרות שעדיין פרוסות בשער לפי שלב 1.
משווים בין התוצאות. כל מדד שמוגדר בגרסה ישנה יותר של API config, צריך להיות מוגדר גם בגרסה החדשה ביותר של API config. אם מדד מסוים חסר בהגדרה הזו, השערים שמשרתים את הגדרת ה-API הישנה יותר נכשלים.
שחזור של הגדרת מכסה תקינה
בודקים את המדדים והמגבלות של המכסות כדי לוודא שהם עקביים בכל ההגדרות הפעילות. כדי לעשות את זה, מבצעים אחת מהפעולות הבאות:
- מעדכנים כל שער של ה-API כך שישתמש בהגדרת ה-API שנוצרה לאחרונה, כפי שמתואר במאמר עדכון שער.
- יוצרים הגדרת API חדשה שמצהירה על כל מדד שמשמש את הגדרות ה-API שעדיין פרוסות, ומשאירים את השערים הקיימים בהגדרות ה-API הנוכחיות שלהם.
כדי למנוע שגיאות בהקצאה, חשוב לשמור על שמות עקביים של מדדים בהגדרות ה-API של אותו API. כשמשנים מכסה, צריך לשנות את הערך של המגבלה ולא את שם המדד.
בקשות API עם זמן אחזור ארוך
כמו ב-Cloud Run ובפונקציות Cloud Run, גם ב-API Gateway יש זמן אחזור של "הפעלה קרה". אם השער לא קיבל תנועה במשך 15 עד 20 דקות, בקשות שנשלחות לשער ב-10 עד 15 השניות הראשונות של ההפעלה הקרה יחוו זמן אחזור של 3 עד 5 שניות.
אם הבעיה נמשכת אחרי תקופת "החימום" הראשונית, צריך לבדוק את יומני הבקשות של שירותי הקצה העורפי שהגדרתם ב-API Config. לדוגמה, אם שירות הקצה העורפי מיושם באמצעות פונקציות Cloud Run, בודקים את הרשומות ב-Cloud Logging של יומן הבקשות של הפונקציה המשויכת של Cloud Functions.
לא ניתן לראות את פרטי היומן
אם ה-API מגיב בצורה תקינה אבל היומנים לא מכילים נתונים, בדרך כלל זה אומר שלא הפעלתם את כל שירותי Google שנדרשים ל-API Gateway.
כדי להשתמש ב-API Gateway, צריך להפעיל את שירותי Google Cloud הבאים:
| שם | שם השירות |
|---|---|
| API Gateway API | apigateway.googleapis.com |
| Service Management API | servicemanagement.googleapis.com |
| Service Control API | servicecontrol.googleapis.com |
כדי להפעיל את השירותים הנדרשים:
מסוף Google Cloud
במסוף Google Cloud , נכנסים לדף APIs & Services > API Library.
- בדף API Library, מזינים את שם ה-API הנדרש בשורת החיפוש.
- בתוצאות החיפוש, בוחרים את דף ה-API.
- בדף ה-API, לוחצים על Enable.
- חוזרים על השלבים האלה לכל אחד מהשירותים שמפורטים בטבלה שלמעלה.
Google Cloud CLI
כדי להפעיל את השירותים, משתמשים בפקודות הבאות:
gcloud services enable apigateway.googleapis.comgcloud services enable servicemanagement.googleapis.comgcloud services enable servicecontrol.googleapis.com
מידע נוסף על שירותי gcloud זמין במאמר שירותי gcloud.