1. מבוא
העדכון האחרון: 2021-05-06
Microservice Rainbow Rumpus
השתתפתם פעם בקרב כדורי שלג שבו אתם זזים וזורקים כדורי שלג על אחרים? אם לא, כדאי לנסות מתישהו! אבל עכשיו, במקום להסתכן בחטיפה פיזית, אתם יכולים לבנות שירות קטן שנגיש לרשת (מיקרו-שירות) שישתתף בקרב אפי נגד מיקרו-שירותים אחרים, ויזרוק קשתות בענן במקום כדורי שלג.
אולי תהיתם… אבל איך מיקרו-שירות יכול "להקפיץ הודעת שגיאה" קשת בענן על מיקרו-שירותים אחרים? מיקרו-שירות יכול לקבל בקשות רשת (בדרך כלל באמצעות HTTP) ולהחזיר תשובות. יש 'מנהל זירה' שישלח למיקרו-שירות שלכם את המצב הנוכחי של הזירה, ואז המיקרו-שירות שלכם יגיב בפקודה שמציינת מה לעשות.
המטרה היא כמובן לנצח, אבל במהלך הדרך תלמדו איך ליצור ולפרוס מיקרו-שירותים ב-Google Cloud.
איך זה עובד
תבנו מיקרו-שירות באמצעות כל טכנולוגיה שתרצו (או תבחרו מתוך תבניות מוכנות של Go, Java, Kotlin, Scala, NodeJS או Python), ואז תפרסו את המיקרו-שירות ב-Google Cloud. אחרי הפריסה, תשלחו לנו את כתובת ה-URL של המיקרו-שירות ואנחנו נוסיף אותו לזירה.
הזירה מכילה את כל השחקנים בקרב נתון. ל-Rainbow Rumpus יהיו זירות משחק משלו. כל שחקן מייצג מיקרו-שירות שנע ממקום למקום וזורק קשתות על השחקנים האחרים.
בערך פעם בשנייה, מנהל הזירה יתקשר למיקרו-שירות שלכם, ישלח את המצב הנוכחי של הזירה (איפה השחקנים), והמיקרו-שירות שלכם יגיב עם פקודה לגבי מה לעשות. בזירה תוכלו להתקדם, לפנות ימינה או שמאלה או לזרוק קשת. הקשת תנוע עד שלושה משבצות בכיוון שאליו פונה השחקן. אם הקשת 'פוגעת' בשחקן אחר, השחקן שזרק את הקשת מקבל נקודה אחת והשחקן שנפגע מאבד נקודה אחת. גודל הזירה מותאם אוטומטית למספר השחקנים הנוכחי.
כך נראה זירה קודמת:

זירת קרב לדוגמה
התנגשויות חוזרות
יכול להיות שבזירה כמה שחקנים ינסו לבצע פעולות סותרות. לדוגמה, שני שחקנים יכולים לנסות לעבור לאותו מקום. במקרה של קונפליקט, המיקרו-שירות עם זמן התגובה המהיר ביותר הוא זה שינצח.
צפייה בקרב
כדי לראות את הביצועים של המיקרו-שירות שלכם בקרב, אפשר להיכנס לזירה בזמן אמת.
Battle API
כדי לעבוד עם מנהל הזירה שלנו, המיקרו-שירות שלכם צריך להטמיע API ספציפי כדי להשתתף בזירה. מנהל הזירה ישלח את המצב הנוכחי של הזירה בבקשת HTTP POST לכתובת ה-URL שתספקו לנו, עם מבנה ה-JSON הבא:
{
"_links": {
"self": {
"href": "https://YOUR_SERVICE_URL"
}
},
"arena": {
"dims": [4,3], // width, height
"state": {
"https://A_PLAYERS_URL": {
"x": 0, // zero-based x position, where 0 = left
"y": 0, // zero-based y position, where 0 = top
"direction": "N", // N = North, W = West, S = South, E = East
"wasHit": false,
"score": 0
}
... // also you and the other players
}
}
}
תגובת ה-HTTP שלכם צריכה להיות עם קוד סטטוס 200 (OK) וגוף תגובה שמכיל את המהלך הבא שלכם, מקודד כתו יחיד באותיות רישיות, אחד מהבאים:
F <- move Forward
R <- turn Right
L <- turn Left
T <- Throw
זה הכול! במאמר הזה נסביר איך פורסים מיקרו-שירות (microservice) ב-Cloud Run, שירות של Google Cloud להרצת מיקרו-שירותים ואפליקציות אחרות.
2. כניסה ל-Google Cloud
כדי לפרוס את המיקרו-שירות (microservice) ב-Cloud Run, צריך להיכנס ל-Google Cloud. נוסיף קרדיט לחשבון שלכם ולא תצטרכו להזין כרטיס אשראי. בדרך כלל, עדיף להשתמש בחשבון לשימוש אישי (למשל gmail.com) במקום בחשבון G Suite, כי לפעמים אדמינים של G Suite מונעים מהמשתמשים שלהם להשתמש בתכונות מסוימות של Google Cloud. בנוסף, מסוף האינטרנט שבו נשתמש אמור לפעול בצורה חלקה עם Chrome או Firefox, אבל יכול להיות שיהיו בעיות ב-Safari.
3. פריסת המיקרו-שירות
אתם יכולים לבנות את המיקרו-שירות בכל טכנולוגיה ולפרוס אותו בכל מקום, כל עוד הוא נגיש לציבור ועומד בדרישות של Battle API. כדי להקל עליכם, נעזור לכם להתחיל עם שירות לדוגמה ולפרוס אותו ב-Cloud Run.
בחירת דוגמה כדי להתחיל
יש הרבה דוגמאות של מיקרו-שירותים של קרבות שאפשר להתחיל מהן:
Kotlin ו-Spring Boot | ||
Kotlin ו-Micronaut | ||
Kotlin ו-Quarkus | ||
Java ו-Spring Boot | ||
Java ו-Quarkus | ||
Go | ||
Node.js ו-Express | ||
Python ו-Flask |
אחרי שמחליטים באיזה קוד לדוגמה להתחיל, לוחצים על הלחצן 'פריסה ב-Cloud Run' שלמעלה. הפעולה הזו תשיק את Cloud Shell (מסוף מבוסס-אינטרנט למכונה וירטואלית בענן) שבו המקור ישוכפל, ואז יבנה לחבילה שניתן לפרוס (קובץ אימג' של קונטיינר Docker), שתועלה ל-Google Container Registry ואז תיפרס ב-Cloud Run.
כשמתבקשים, מציינים את האזור us-central1.
צילום המסך שלמטה מציג את הפלט של Cloud Shell עבור בנייה ופריסה של מיקרו-שירות

אימות הפעולה של המיקרו-שירות
ב-Cloud Shell, שולחים בקשה למיקרו-שירות החדש שהופעל, ומחליפים את YOUR_SERVICE_URL בכתובת ה-URL של השירות (שמופיעה ב-Cloud Shell אחרי השורה Your application is now live here):
curl -d '{
"_links": {
"self": {
"href": "https://foo.com"
}
},
"arena": {
"dims": [4,3],
"state": {
"https://foo.com": {
"x": 0,
"y": 0,
"direction": "N",
"wasHit": false,
"score": 0
}
}
}
}' -H "Content-Type: application/json" -X POST -w "\n" \
https://YOUR_SERVICE_URL
אמורה להופיע מחרוזת התגובה F, L, R או T.
4. בקשה לקבלת בקשת ההצטרפות לזירה
כדי להצטרף ל-Rainbow Rumpus, צריך להצטרף לזירה. פותחים את rainbowrumpus.dev ולוחצים על 'הצטרפות' בזירה שבה תספקו את כתובת ה-URL של המיקרו-שירות.
5. ביצוע שינויים ופריסה
לפני שתוכלו לבצע שינויים, תצטרכו להגדיר ב-Cloud Shell מידע על פרויקט GCP ועל הדוגמה שבה השתמשתם. קודם צריך להציג רשימה של הפרויקטים ב-GCP:
gcloud projects list
סביר להניח שיש לכם רק פרויקט אחד. מעתיקים את PROJECT_ID מהעמודה הראשונה ומדביקים אותו בפקודה הבאה (מחליפים את YOUR_PROJECT_ID במזהה הפרויקט בפועל), כדי להגדיר משתנה סביבה שנשתמש בו בפקודות מאוחרות יותר:
export PROJECT_ID=YOUR_PROJECT_ID
עכשיו מגדירים עוד משתנה סביבה לדוגמה שבה השתמשתם, כדי שנוכל לציין בפקודות הבאות את שם הספרייה והשירות הנכונים:
# Copy and paste ONLY ONE of these export SAMPLE=kotlin-micronaut export SAMPLE=kotlin-quarkus export SAMPLE=kotlin-springboot export SAMPLE=java-quarkus export SAMPLE=java-springboot export SAMPLE=go export SAMPLE=nodejs export SAMPLE=python
עכשיו אפשר לערוך את המקור של המיקרו-שירות מתוך Cloud Shell. כדי לפתוח את Cloud Shell Editor מבוסס-האינטרנט, מריצים את הפקודה הבאה:
cloudshell edit cloudbowl-microservice-game/samples/$SAMPLE/README.md
יוצגו הוראות נוספות לביצוע שינויים.

Cloud Shell עם העורך והפרויקט לדוגמה פתוח
אחרי ששומרים את השינויים, מפעילים את האפליקציה ב-Cloud Shell באמצעות הפקודה מהקובץ README.md. לפני כן, צריך לוודא שאתם נמצאים בספריית הדוגמה הנכונה ב-Cloud Shell:
cd cloudbowl-microservice-game/samples/$SAMPLE
אחרי שהאפליקציה פועלת, פותחים כרטיסייה חדשה ב-Cloud Shell ובודקים את השירות באמצעות curl:
curl -d '{
"_links": {
"self": {
"href": "https://foo.com"
}
},
"arena": {
"dims": [4,3],
"state": {
"https://foo.com": {
"x": 0,
"y": 0,
"direction": "N",
"wasHit": false,
"score": 0
}
}
}
}' -H "Content-Type: application/json" -X POST -w "\n" \
http://localhost:8080
כשמוכנים לפרוס את השינויים, בונים את הפרויקט ב-Cloud Shell באמצעות הפקודה pack. הפקודה הזו משתמשת ב-Buildpacks כדי לזהות את סוג הפרויקט, לקמפל אותו וליצור את הארטיפקט שניתן לפריסה (קובץ אימג' של קונטיינר Docker).
# Make sure you are in a Cloud Shell tab where you set the PROJECT_ID # and SAMPLE env vars. Otherwise, set them again. pack build gcr.io/$PROJECT_ID/$SAMPLE \ --path ~/cloudbowl-microservice-game/samples/$SAMPLE \ --builder gcr.io/buildpacks/builder
אחרי שיוצרים את קובץ האימג' של הקונטיינר, משתמשים בפקודה docker (ב-Cloud Shell) כדי להעביר בדחיפה את קובץ האימג' של הקונטיינר אל Google Container Registry, כדי ש-Cloud Run יוכל לגשת אליו:
docker push gcr.io/$PROJECT_ID/$SAMPLE
עכשיו פורסים את הגרסה החדשה ב-Cloud Run:
gcloud run deploy $SAMPLE \
--project=$PROJECT_ID \
--platform=managed \
--region=us-central1 \
--image=gcr.io/$PROJECT_ID/$SAMPLE \
--allow-unauthenticated
מעכשיו, בזירה תהיה הגרסה החדשה שלכם.
6. פיתוח באופן מקומי (אופציונלי)
כדי לעבוד על הפרויקט באופן מקומי באמצעות סביבת פיתוח משולבת משלכם, פועלים לפי השלבים הבאים:
- [ב-Cloud Shell] מכווצים את הדוגמה:
# Make sure the SAMPLE env var is still set. If not, re-set it. cd ~/cloudbowl-microservice-game/samples zip -r cloudbowl-sample.zip $SAMPLE
- [In Cloud Shell] מורידים את קובץ ה-ZIP למחשב:
cloudshell download-file cloudbowl-sample.zip
- [במחשב] מבטלים את הדחיסה של הקובץ, מבצעים את השינויים ובודקים אותם.
- [במחשב] מתקינים את ה-CLI של gcloud
- [במחשב] נכנסים ל-Google Cloud:
gcloud auth login
- [במחשב שלכם] מגדירים את משתני הסביבה
PROJECT_IDו-SAMPLEלאותם ערכים כמו ב-Cloud Shell. - [במכונה שלכם] משתמשים ב-Cloud Build כדי לבנות את הקונטיינר (מתיקיית הבסיס של הפרויקט):
gcloud alpha builds submit . \ --pack=image=gcr.io/$PROJECT_ID/$SAMPLE \ --project=$PROJECT_ID
- [במחשב] פורסים את הקונטיינר החדש:
gcloud run deploy $SAMPLE \ --project=$PROJECT_ID \ --platform=managed \ --region=us-central1 \ --image=gcr.io/$PROJECT_ID/$SAMPLE \ --allow-unauthenticated
7. פיתוח רציף (CD)
הגדרת SCM
הגדרת GitHub כדי שתוכלו לשתף פעולה עם הצוות שלכם במיקרו-שירות:
- כניסה ל-GitHub
- יצירת מאגר חדש
- אם אתם עובדים במחשב המקומי, אתם יכולים להשתמש בממשק שורת הפקודה (CLI) של git או באפליקציית GUI של GitHub Desktop (ב-Windows או ב-Mac). אם אתם משתמשים ב-Cloud Shell, תצטרכו להשתמש ב-git CLI. כדי להעלות את הקוד של המיקרו-שירות ל-GitHub, פועלים לפי ההוראות ל-CLI או ל-GitHub Desktop.
דחיפת הקוד באמצעות git CLI
- פועלים לפי ההוראות לשימוש ב-git over https עם אסימון גישה אישי.
- בוחרים בהיקף 'repo'
- הגדרת git:
git config --global credential.helper \ 'cache --timeout=172800' git config --global push.default current git config --global user.email "YOUR@EMAIL" git config --global user.name "YOUR NAME"
- הגדרת משתני סביבה לארגון ולמאגר GitHub (
https://github.com/ORG/REPO)
export GITHUB_ORG=YOUR_GITHUB_ORG export GITHUB_REPO=YOUR_GITHUB_REPO
- שליחת הקוד למאגר החדש
# Make sure the SAMPLE env var is still set. If not, re-set it. cd ~/cloudbowl-microservice-game/samples/$SAMPLE git init git add . git commit -m init git remote add origin https://github.com/$GITHUB_ORG/$GITHUB_REPO.git git branch -M main # This will now ask for your GitHub username & password # for the password use the personal access token git push -u origin main
- אחרי שמבצעים שינויים, אפשר לבצע commit ולדחוף את השינויים ל-GitHub:
git add . git status git diff --staged git commit -am "my changes" git push
איך מעלים את הקוד באמצעות GitHub Desktop
- מורידים את הקוד באמצעות ההוראות מהמעבדה הקודמת בנושא 'פיתוח מקומי'
- מתקינים את GitHub Desktop, מפעילים אותו ונכנסים לחשבון.
- שכפול המאגר החדש שנוצר

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

- פרסום ההסתעפות הראשית ב-GitHub
הגדרת פריסה רציפה ב-Cloud Run
אחרי שמגדירים את SCM ב-GitHub, אפשר להגדיר פיתוח רציף (continuous delivery) כך שבכל פעם שדוחפים קומיטים חדשים להסתעפות main, מערכת Cloud Build תיצור פריסה אוטומטית של השינויים. אפשר גם להוסיף שילוב רציף שמריץ את הבדיקות לפני הפריסה, אבל השלב הזה נשאר כתרגיל בשבילכם כי הדוגמאות המוכנות לשימוש לא מכילות בדיקות.
- במסוף Cloud, עוברים לשירות Cloud Run
- לוחצים על הלחצן 'הגדרת פריסה רציפה'.
- אימות באמצעות GitHub ובחירת המאגר של המיקרו-שירות

- בוחרים את מאגר GitHub ומגדירים את ההסתעפות ל:
^main$

- הגדרת סוג ה-Build לשימוש ב-Buildpacks
- לוחצים על Save (שמירה) כדי להגדיר פריסה רציפה.
8. ניראות (observability)
דברים מתקלקלים. התכונה 'יכולת צפייה' מאפשרת לנו לדעת מתי זה קורה ולאבחן למה. מדדים מציגים לנו נתונים על תקינות השירות והשימוש בו. היומנים מציגים לנו את המידע שהוגדר ידנית ומופק מהשירות שלנו. התראות מאפשרות לנו לקבל הודעה כשמשהו משתבש. בואו נתעמק בכל אחד מהם.
מדדים
- מחפשים את השירות ברשימת שירותי Cloud Run.
- לוחצים על שם השירות כדי לעבור למרכז הבקרה של המדדים שלו.

- לוחצים על תפריט ⋮ של מדד מסוים ואז בוחרים באפשרות 'הצגה ב-Metrics Explorer'.
- עכשיו אפשר לשנות את מדדי המשאבים, המסננים, הקיבוץ ואפשרויות אחרות. לדוגמה, אתם יכולים לראות את זמן האחזור הממוצע של כל השירותים:

יומנים
פלט STDOUT משירותים נשלח למערכת Cloud Logging של Google. אפשר לגשת לתצוגת יומן בסיסית מדף האדמין של שירות Cloud Run, למשל:

בלוגים של Cloud Run אפשר לסנן לפי חומרה ולסנן את הלוגים. כדי ליהנות מגמישות רבה יותר, לוחצים על: 
התראות
- יוצרים כתובת URL לבדיקת תקינות בשביל השירות.
- ב-Spring Boot, פשוט מוסיפים את יחסי התלות הבאים:
org.springframework.boot:spring-boot-starter-actuator
- יוצרים או מעדכנים את
src/main/resources/application.propertiesומשביתים את בדיקת נפח הדיסק:
management.health.diskspace.enabled=false
- יוצרים התראה על זמני פעילות ומציינים את הפרוטוקול, שם המארח והנתיב. ב-Spring Boot, הנתיב הוא:
/actuator/health - בדיקת ההתראה

- יצירת ההתראה
9. מזל טוב
הצלחתם לבנות ולפרוס מיקרו-שירות שיכול להילחם במיקרו-שירותים אחרים. בהצלחה!