בדף הזה מפורטות הנחיות ושיטות מומלצות להפעלת WebSockets או שירותי סטרימינג אחרים ב-Cloud Run, ולכתיבת לקוחות לשירותים כאלה.
יש תמיכה באפליקציות WebSockets ב-Cloud Run, ולא נדרשות הגדרות נוספות. עם זאת, סטרימינג של WebSockets הוא בקשות HTTP, שעדיין כפופות לזמן הקצוב לתפוגה של הבקשה שהוגדר לשירות Cloud Run, ולכן צריך לבצע את הפעולות הבאות:
- כדאי להגדיל את משך הזמן של הזמן הקצוב לתפוגה של הבקשה למשך הזמן המקסימלי שבו רוצים להשאיר את הזרם של WebSockets פתוח, למשל 60 דקות.
- מוודאים שהלקוחות יכולים להתחבר מחדש.
- מומלץ להשתמש בזיקה לסשן כדי שהלקוחות יתחברו מחדש לאותו מופע כמה שיותר פעמים.
- לא מפעילים את האפשרות HTTP/2 end-to-end.
למרות שזיקה לסשן ב-Cloud Run מספקת את הזיקה לסשן הטובה ביותר, בקשות חדשות של WebSockets עדיין יכולות להתחבר למופעים שונים, בגלל איזון העומסים המובנה. כדי לפתור את הבעיה, צריך לסנכרן את הנתונים בין המופעים.
שימו לב: אם אתם משתמשים ב-Cloud Load Balancing, יש גם תמיכה ב-WebSockets ב-Cloud Run.
פריסת שירות לדוגמה של WebSockets
אפשר להשתמש ב-Cloud Shell כדי לפרוס במהירות שירות ללוח אינטראקטיבי לדוגמה שמשתמש ב-WebSockets עם Cloud Run: פריסת דוגמה
לחלופין, אם רוצים לפרוס את שירות הלוח הווירטואלי לדוגמה באופן ידני:
משכפלים את מאגר Socket.IO באופן מקומי באמצעות כלי שורת הפקודה git:
git clone https://github.com/socketio/socket.io.gitעוברים לספרייה לדוגמה:
cd socket.io/examples/whiteboard/פורסים שירות חדש ב-Cloud Run על ידי בניית השירות מקוד המקור באמצעות Google Cloud CLI:
gcloud run deploy whiteboard --allow-unauthenticated --source=.אחרי פריסת השירות, פותחים שתי כרטיסיות נפרדות בדפדפן ועוברים לכתובת ה-URL של השירות. כל מה שמציירים בכרטיסייה אחת מועבר לכרטיסייה השנייה (ולהפך), כי הלקוחות מחוברים לאותו מופע באמצעות WebSockets.
מדריך מלא לדוגמה של צ'אט ב-WebSockets
אם אתם רוצים לקבל הסבר מפורט על הקוד, תוכלו לעיין בדוגמאות קוד נוספות בנושא יצירת שירות צ'אט ב-WebSocket עבור Cloud Run.
שיטות מומלצות
החלק הכי מסובך ביצירת שירותי WebSockets ב-Cloud Run הוא סנכרון הנתונים בין כמה מופעים של Cloud Run. הדבר מסובך בגלל ההתאמה האוטומטית לעומס והאופי חסר המצב של המופעים, ובגלל המגבלות על בו-זמניות ועל זמן קצוב לתפוגה של בקשות.
טיפול בפסק זמן של בקשות ובחיבורים מחדש של לקוחות
בקשות WebSockets נחשבות ב-Cloud Run לבקשות HTTP ארוכות טווח. הם כפופים לפסק זמן של בקשות (נכון לעכשיו, עד 60 דקות וברירת המחדל היא 5 דקות) גם אם שרת האפליקציות שלכם לא אוכף פסק זמן.
לכן, אם הלקוח ישאיר את החיבור פתוח למשך זמן ארוך יותר מהזמן הקצוב לתפוגה שנדרש והוגדר לשירות Cloud Run, החיבור של הלקוח ינותק כשהבקשה תגיע לזמן הקצוב לתפוגה.
לכן, לקוחות WebSockets שמתחברים ל-Cloud Run צריכים לטפל בחיבור מחדש לשרת אם פג הזמן הקצוב לתגובה לבקשה או אם השרת מתנתק. אפשר לעשות את זה בלקוחות מבוססי-דפדפן באמצעות ספריות כמו reconnecting-websocket, או באמצעות טיפול באירועי 'ניתוק' אם משתמשים בספריית SocketIO.
חיוב על שימוש ב-WebSockets
מכונת Cloud Run עם חיבור WebSocket פתוח נחשבת פעילה, ולכן מוקצה לה CPU והשירות מחויב לפי חיוב מבוסס-מכונה.
הגדלת מספר המשימות שאפשר להריץ בו-זמנית
שירותי WebSockets מתוכננים בדרך כלל לטפל בהרבה חיבורים בו-זמנית. מכיוון ש-Cloud Run תומך בחיבורים בו-זמניים (עד 1,000 לכל קונטיינר), Google ממליצה להגדיל את ההגדרה של מקסימום מקביליות בקונטיינר לערך גבוה יותר מהערך שמוגדר כברירת מחדל, אם השירות יכול להתמודד עם העומס באמצעות המשאבים שמוקצים לו.
מידע על סשנים קבועים (זיקה לסשן)
מכיוון שחיבורי WebSockets הם חיבורים עם מצב, הלקוח יישאר מחובר לאותו קונטיינר ב-Cloud Run לאורך משך החיים של החיבור. כך מתקבלת באופן טבעי שמירת נתונים של סשן בהקשר של חיבור WebSocket יחיד.
אם יש כמה חיבורי WebSockets עוקבים, אפשר להגדיר את שירות Cloud Run כך שישתמש בזיקה לסשן (session affinity), אבל ההעדפה הזו היא במקרה הטוב, ולכן בקשות WebSockets עדיין יכולות להגיע למופעים שונים. יכול להיות שיהיו לקוחות שיתחברו לשירות Cloud Run שלכם ויקבלו שירות ממופעים שונים שלא מתואמים או משתפים נתונים.
כדי לפתור את הבעיה הזו, צריך להשתמש באחסון נתונים חיצוני כדי לסנכרן את המצב בין מכונות Cloud Run, כמו שמוסבר בקטע הבא.
סנכרון נתונים בין מופעים
כדי לוודא שהלקוחות שמתחברים לשירות Cloud Run מקבלים את אותם נתונים מהחיבור ל-WebSockets, צריך לסנכרן את הנתונים.
לדוגמה, נניח שאתם בונים שירות של חדר צ'אט באמצעות WebSockets והגדרתם את המקבילות המקסימלית ל-1000. אם יותר מ-1000
משתמשים יתחברו לשירות הזה בו-זמנית, הם יקבלו שירות ממופעים שונים, ולכן הם לא יוכלו לראות את אותן הודעות בחדר הצ'אט.
כדי לסנכרן נתונים בין מופעי Cloud Run, כמו קבלת ההודעות שפורסמו בחדר צ'אט מכל המופעים, צריך מערכת אחסון נתונים חיצונית, כמו מסד נתונים או תור הודעות.
אם משתמשים במסד נתונים חיצוני כמו Cloud SQL, אפשר לשלוח הודעות למסד הנתונים ולבצע שאילתות ממסד הנתונים באופן תקופתי. עם זאת, חשוב לשים לב שלמופעים של Cloud Run אין מעבד כשהקונטיינר לא מטפל בבקשות. אם השירות שלכם מטפל בעיקר בבקשות WebSockets, המערכת תקצה לכם ליבות CPU כל עוד לפחות לקוח אחד מחובר אליו.
תורי הודעות מתאימים יותר לסנכרון נתונים בין קונטיינרים של Cloud Run בזמן אמת, כי תורי ההודעות החיצוניים לא יכולים לפנות לכל מופע כדי לבצע 'דחיפה' של נתונים. השירותים צריכים 'למשוך' הודעות חדשות מתור ההודעות על ידי יצירת חיבור לתור ההודעות.
Google ממליצה להשתמש במערכות חיצוניות לתור הודעות כמו Redis Pub/Sub (Memorystore) או עדכונים בזמן אמת ב-Firestore, שיכולות לספק עדכונים לכל המופעים דרך חיבורים שהופעלו על ידי מופע המאגר.
שימוש ב-Redis Pub/Sub
אפשר להשתמש במנגנון Redis Pub/Sub על ידי יצירת מכונת Redis מ-Memorystore. אם אתם משתמשים בספריית Socket.IO ל-WebSockets, אתם יכולים להשתמש במתאם redis שלה.
באדריכלות שמבוססת על Redis, כל מופע של Cloud Run יוצר חיבור לטווח ארוך לערוץ Redis שמכיל את ההודעות שהתקבלו (באמצעות הפקודה SUBSCRIBE). אחרי שמופעים של מאגרי תגים מקבלים הודעה חדשה בערוץ, הם יכולים לשלוח אותה ללקוחות שלהם באמצעות WebSockets בזמן אמת.
באופן דומה, כשלקוח שולח הודעה באמצעות WebSockets, המופע שמקבל את ההודעה מפרסם את ההודעה בערוץ Redis (באמצעות הפקודה PUBLISH), ומופעים אחרים שמנויים לערוץ הזה יקבלו את ההודעה.
אם אתם רוצים לקבל הסבר מפורט על הקוד, תוכלו לעיין בדוגמאות קוד נוספות בנושא יצירת שירות צ'אט ב-WebSocket עבור Cloud Run.