1. מבוא

Eventarc מאפשר לחבר בקלות שירותי Cloud Run לאירועים ממגוון מקורות. הוא מאפשר לכם לבנות ארכיטקטורות מבוססות-אירועים שבהן מיקרו-שירותים (microservices) הם בצימוד חלש ומבוזרים. הוא מטפל בהטמעה, בשליחה, באבטחה, בהרשאה ובטיפול בשגיאות של אירועים.
Workflows היא פלטפורמת תזמור מנוהלת במלואה שמבצעת שירותים בסדר שאתם מגדירים: תהליך עבודה. בתהליכי העבודה האלה אפשר לשלב שירותים שמארחים ב-Cloud Run או ב-Cloud Functions, שירותי Google Cloud כמו Cloud Vision AI ו-BigQuery, וכל API מבוסס-HTTP.
בשיעור הזה תלמדו איך ליצור תזמור של מיקרו-שירותים מבוססי-אירועים לעיבוד תמונות. תשתמשו ב-Workflows כדי לתזמן את הסדר, את הקלט ואת הפלט של 4 פונקציות של Cloud Functions לעיבוד תמונות. לאחר מכן תפעילו את התזמור כדי להגיב לאירועים ב-Cloud Storage בצורה משוחררת באמצעות Eventarc.
בסופו של דבר, תהיה לכם ארכיטקטורה גמישה אך מובנית ללא שרת לעיבוד תמונות.

מה תלמדו
- סקירה כללית של Eventarc ו-Workflows
- איך פורסים שירותי Cloud Functions
- איך מתזמרים שירותים באמצעות Workflows
- איך גורמים ל-Workflows להגיב לאירועים ב-Cloud Storage באמצעות Eventarc
2. הגדרה ודרישות
הגדרת סביבה בקצב עצמי
- נכנסים ל-Google Cloud Console ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, אתם צריכים ליצור חשבון.



- שם הפרויקט הוא השם המוצג של המשתתפים בפרויקט הזה. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
- מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-
PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא נשארת לאורך הפרויקט. - לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. מידע נוסף על שלושת הערכים האלה מופיע במאמרי העזרה.
- בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולוודא שלא תחויבו על שימוש בהם אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.
הפעלת Cloud Shell
אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה תשתמשו ב-Google Cloud Shell, סביבת שורת פקודה שפועלת ב-Cloud.
ב-Google Cloud Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

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

המכונה הווירטואלית הזו טעונה בכל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-Codelab הזה בדפדפן. לא צריך להתקין שום דבר.
הגדרת gcloud
ב-Cloud Shell, מגדירים את מזהה הפרויקט ואת האזור שבו רוצים לפרוס את האפליקציה. שומרים אותם כמשתנים PROJECT_ID ו-REGION. אפשר לעיין במיקומים של Cloud Functions כדי לראות את האזורים הזמינים.
PROJECT_ID=your-project-id gcloud config set project $PROJECT_ID
קבלת קוד המקור
קוד המקור של האפליקציה נמצא בתיקייה processing-pipelines במאגר eventarc-samples.
משכפלים את המאגר:
git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git
עוברים לתיקייה eventarc-samples/processing-pipelines:
cd eventarc-samples/processing-pipelines
3. סקירה כללית של הארכיטקטורה
זו הארכיטקטורה של האפליקציה:

- תמונה נשמרת בקטגוריית קלט שיוצרת אירוע יצירה ב-Cloud Storage.
- אירוע יצירה ב-Cloud Storage נקרא על ידי Eventarc באמצעות טריגר של Cloud Storage ומועבר אל Workflows כ-CloudEvent.
- בשלב הראשון של תהליך העבודה, Filter, שירות Cloud Functions, משתמש ב-Vision API כדי לקבוע אם התמונה בטוחה. אם התמונה בטוחה, כלי Workflows ממשיך לשלבים הבאים.
- בשלב השני של תהליך העבודה, Labeler, שירות Cloud Functions, מחלץ תוויות של התמונה באמצעות Vision API ושומר את התוויות בדלי הפלט.
- בשלב השלישי, Resizer, שירות נוסף של Cloud Functions, משנה את גודל התמונה באמצעות ImageSharp ושומר את התמונה שגודלה שונה בדלי הפלט.
- בשלב האחרון, Watermarker, שירות נוסף של Cloud Functions, מוסיף סימן מים של תוויות מ-Labeler לתמונה שגודלה שונה באמצעות ImageSharp, ושומר את התמונה בקטגוריית הפלט.
האפליקציה מופעלת על ידי אירוע ב-Cloud Storage, ולכן היא מבוססת-אירועים. עיבוד התמונות מתבצע בתהליך עבודה, ולכן זהו תזמור. בסופו של דבר, מדובר בתזמור מבוסס-אירועים של ארכיטקטורה גמישה אך מובנית ללא שרת, לעיבוד תמונות.
4. יצירת קטגוריות
יוצרים באקט קלט שבו המשתמשים יכולים להעלות את התמונות, ובאקט פלט שבו צינור העיבוד של התמונות יכול לשמור את התמונות המעובדות.
מריצים את הפקודה הבאה ב-Cloud Shell:
REGION=us-central1 BUCKET1=$PROJECT_ID-images-input-$RANDOM BUCKET2=$PROJECT_ID-images-output-$RANDOM gsutil mb -l $REGION gs://$BUCKET1 gsutil mb -l $REGION gs://$BUCKET2
5. פריסת שירות המסננים
נתחיל בפריסת השירות הראשון. שירות Cloud Functions מקבל את פרטי הדלי והקובץ, קובע אם התמונה בטוחה באמצעות Vision API ומחזיר את התוצאה.
קודם מפעילים את השירותים הנדרשים ל-Cloud Functions gen2 ול-Vision API:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ run.googleapis.com \ vision.googleapis.com
בתיקייה ברמה העליונה processing-pipelines, פורסים את השירות:
SERVICE_NAME=filter gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --entry-point Filter.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp
אחרי שפורסים את הפונקציה, מגדירים את כתובת ה-URL של השירות במשתנה. נצטרך אותה בהמשך:
FILTER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
6. פריסת שירות לסימון תוויות
שירות Cloud Functions השני מקבל את פרטי הקטגוריה והקובץ, מחלץ את התוויות של התמונה באמצעות Vision API ושומר את התוויות בקטגוריית הפלט.
בתיקייה ברמה העליונה processing-pipelines, פורסים את השירות:
SERVICE_NAME=labeler gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Labeler.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp
אחרי שפורסים את הפונקציה, מגדירים את כתובת ה-URL של השירות במשתנה. נצטרך אותה בהמשך:
LABELER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
7. פריסת שירות לשינוי גודל
שירות Cloud Functions מקבל את פרטי הקטגוריה והקובץ, משנה את גודל התמונה באמצעות ImageSharp ושומר את התמונה בקטגוריית הפלט.
בתיקייה ברמה העליונה processing-pipelines, פורסים את השירות:
SERVICE_NAME=resizer gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Resizer.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp \ --timeout=120s
שימו לב לערך timeout של 2 דקות, כדי לאפשר לפונקציית שינוי הגודל זמן נוסף לעיבוד.
אחרי שפורסים את הפונקציה, מגדירים את כתובת ה-URL של השירות במשתנה. נצטרך אותה בהמשך:
RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
8. פריסת שירות לסימון מים
שירות Cloud Functions מקבל את המידע על הקטגוריה, הקובץ והתוויות, קורא את הקובץ, מוסיף את התוויות כסימן מים לתמונה באמצעות ImageSharp ושומר את התמונה בקטגוריית הפלט.
בתיקייה ברמה העליונה processing-pipelines, פורסים את השירות:
SERVICE_NAME=watermarker gcloud functions deploy $SERVICE_NAME \ --gen2 \ --allow-unauthenticated \ --runtime dotnet3 \ --trigger-http \ --region=$REGION \ --set-env-vars BUCKET=$BUCKET2 \ --entry-point Watermarker.Function \ --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp
אחרי שפורסים את הפונקציה, מגדירים את כתובת ה-URL של השירות במשתנה. נצטרך אותה בהמשך:
WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')
בשלב הזה, כל ארבע הפונקציות של Cloud Functions צריכות להיות פרוסות ופעילות:

9. הגדרה ופריסה של תהליך עבודה
אפשר להשתמש בתהליכי עבודה כדי לשלב בין שירותים של מסננים, תוויות, שינוי גודל וסימון מים בתהליך עבודה. תהליכי העבודה יתזמנו את הקריאות לשירותים האלה בסדר ובפרמטרים שנגדיר.
קודם כל, מפעילים את השירותים הנדרשים ל-Workflows:
gcloud services enable \ workflows.googleapis.com \ workflowexecutions.googleapis.com
הגדר
Workflows מקבלת CloudEvent כפרמטר. הנתונים האלה יגיעו מ-Eventarc אחרי שניצור טריגר. בשני השלבים הראשונים, Workflows מתעד את האירוע ומחלץ ממנו את פרטי הקטגוריה והקובץ:
main:
params: [event]
steps:
- log_event:
call: sys.log
args:
text: ${event}
severity: INFO
- extract_bucket_and_file:
assign:
- bucket: ${event.data.bucket}
- file: ${event.data.name}
בשלב filter, Workflows מבצע קריאה לשירות הסינון שפרסנו קודם. לאחר מכן, המערכת מתעדת את הקובץ ביומן ובודקת את הבטיחות שלו:
- filter:
call: http.post
args:
url: FILTER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: filterResponse
- log_safety:
call: sys.log
args:
text: ${filterResponse.body.safe}
severity: INFO
- check_safety:
switch:
- condition: ${filterResponse.body.safe == true}
next: label
next: end
בשלב label, כלי Workflows מבצע קריאה לשירות התיוג ומתעד את התגובה (3 התוויות העליונות):
- label:
call: http.post
args:
url: LABELER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: labelResponse
בשלב resize, כלי זרימות העבודה מבצע קריאה לשירות שינוי הגודל ומתעד את התגובה (המאגר והקובץ של התמונה שגודלה שונה):
- resize:
call: http.post
args:
url: RESIZER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${bucket}
file: ${file}
result: resizeResponse
בשלב watermark, כלי Workflows קורא לשירות סימון המים עם התמונה והתוויות שגודלן שונה, ומתעד את התוצאה (התמונה שגודלה שונה וסומנה בסימן מים):
- watermark:
call: http.post
args:
url: WATERMARKER_URL # TODO: Replace
auth:
type: OIDC
body:
bucket: ${resizeResponse.body.bucket}
file: ${resizeResponse.body.file}
labels: ${labelResponse.body.labels}
result: watermarkResponse
בשלב final, כלי Workflows מחזיר את קוד הסטטוס HTTP משירותי התיוג, שינוי הגודל והוספת סימן המים:
- final:
return:
label: ${labelResponse.code}
resize: ${resizeResponse.code}
watermark: ${watermarkResponse.code}
פריסה
לפני שמפעילים את תהליך העבודה, צריך לוודא שכתובות ה-URL של השירות הוחלפו בכתובות ה-URL של הפונקציות שהופעלו, באופן ידני או באמצעות sed:
בתוך התיקייה ברמה העליונה processing-pipelines, עוברים לתיקייה image-v3 שבה נמצא הקובץ workflows.yaml:
cd image-v3/
מריצים את הפקודה sed כדי להחליף את כתובות ה-URL של placeholder בכתובות ה-URL בפועל של השירותים שנפרסו:
sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml
sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml
sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml
sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml
פורסים את תהליך העבודה:
WORKFLOW_NAME=image-processing
gcloud workflows deploy $WORKFLOW_NAME \
--source=workflow.yaml \
--location=$REGION
אחרי כמה שניות, תראו שהתהליך העסקי נפרס במסוף:

10. יצירת גורם מפעיל
אחרי פריסת תהליך העבודה, השלב האחרון הוא לקשר אותו לאירועים ב-Cloud Storage באמצעות טריגר של Eventarc.
הגדרה חד פעמית
קודם מפעילים את השירותים הנדרשים ל-Eventarc:
gcloud services enable \ eventarc.googleapis.com
יוצרים חשבון שירות שישמש בטריגר Eventarc.
SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name="Eventarc trigger image processing service account"
מקצים את התפקיד workflows.invoker, כדי שאפשר יהיה להשתמש בחשבון השירות להפעלת Workflows מ-Eventarc:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/workflows.invoker \ --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
מקצים את התפקיד eventarc.eventReceiver כדי שאפשר יהיה להשתמש בחשבון השירות
טריגר של Cloud Storage:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/eventarc.eventReceiver \ --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
מקצים את התפקיד pubsub.publisher לחשבון השירות של Cloud Storage. ההרשאה הזו נדרשת לטריגר Cloud Storage של Eventarc:
STORAGE_SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_ID)"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:$STORAGE_SERVICE_ACCOUNT \
--role roles/pubsub.publisher
יצירה
מריצים את הפקודה הבאה כדי ליצור טריגר. הטריגר הזה מסנן אירועים של יצירת קבצים חדשים מקטגוריית הקלט של Cloud Storage ומעביר אותם אל זרימת העבודה שהגדרנו קודם:
TRIGGER_NAME=trigger-image-processing gcloud eventarc triggers create $TRIGGER_NAME \ --location=$REGION \ --destination-workflow=$WORKFLOW_NAME \ --destination-workflow-location=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET1" \ --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
אפשר לראות שהטריגר נוצר ומוכן בקטע Eventarc במסוף Cloud:

11. בדיקת צינור עיבוד הנתונים
צינור העיבוד של התמונות מוכן לקבל אירועים מ-Cloud Storage. כדי לבדוק את צינור הנתונים, מעלים תמונה לקטגוריית הקלט:
gsutil cp beach.jpg gs://$BUCKET1
מיד אחרי העלאת התמונה, אמורה להופיע הפעלה של Workflows במצב פעיל:

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

אם תציגו את התוכן של דלי הפלט, תראו את התמונה שגודלה שונה, את התמונה שגודלה שונה ונוסף לה סימן מים, ואת התוויות של התמונה:
gsutil ls gs://$BUCKET2 gs://$PROJECT_ID-images-output-$RANDOM/beach-400x400-watermark.jpeg gs://$PROJECT_ID-images-output-$RANDOM/beach-400x400.png gs://$PROJECT_ID-images-output-$RANDOM/beach-labels.txt
כדי לבדוק, אפשר לפתוח את התמונה שגודלה שונה ונוסף לה סימן מים כדי לראות את התוצאה:

12. מזל טוב
כל הכבוד, סיימתם את ה-Codelab!
מה נכלל
- סקירה כללית של Eventarc ו-Workflows
- איך פורסים שירותי Cloud Functions
- איך מתזמרים שירותים באמצעות Workflows
- איך גורמים ל-Workflows להגיב לאירועים ב-Cloud Storage באמצעות Eventarc