יצירת תזמור מבוסס-אירועים באמצעות Eventarc ו-Workflows

1. מבוא

f2f35f5c40b91a3c.png c637dcc97f298e7e.png c4a9d5b95f111710.png

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

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

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

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

b75a14a4268cbe73.png

מה תלמדו

  • סקירה כללית של Eventarc ו-Workflows
  • איך פורסים שירותי Cloud Functions
  • איך מתזמרים שירותים באמצעות Workflows
  • איך גורמים ל-Workflows להגיב לאירועים ב-Cloud Storage באמצעות Eventarc

2. הגדרה ודרישות

הגדרת סביבה בקצב עצמי

  1. נכנסים ל-Google Cloud Console ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, אתם צריכים ליצור חשבון.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

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

הפעלת Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה תשתמשו ב-Google Cloud Shell, סביבת שורת פקודה שפועלת ב-Cloud.

ב-Google Cloud Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

הפעלת Cloud Shell

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

צילום מסך של טרמינל Google 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. סקירה כללית של הארכיטקטורה

זו הארכיטקטורה של האפליקציה:

7b810e1505054c0c.png

  1. תמונה נשמרת בקטגוריית קלט שיוצרת אירוע יצירה ב-Cloud Storage.
  2. אירוע יצירה ב-Cloud Storage נקרא על ידי Eventarc באמצעות טריגר של Cloud Storage ומועבר אל Workflows כ-CloudEvent.
  3. בשלב הראשון של תהליך העבודה, Filter, שירות Cloud Functions, משתמש ב-Vision API כדי לקבוע אם התמונה בטוחה. אם התמונה בטוחה, כלי Workflows ממשיך לשלבים הבאים.
  4. בשלב השני של תהליך העבודה, Labeler, שירות Cloud Functions, מחלץ תוויות של התמונה באמצעות Vision API ושומר את התוויות בדלי הפלט.
  5. בשלב השלישי, Resizer, שירות נוסף של Cloud Functions, משנה את גודל התמונה באמצעות ImageSharp ושומר את התמונה שגודלה שונה בדלי הפלט.
  6. בשלב האחרון, 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 צריכות להיות פרוסות ופעילות:

fe662925cb0121e9.png

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

אחרי כמה שניות, תראו שהתהליך העסקי נפרס במסוף:

a5f537f2b3f3bd3.png

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:

a5f4301863d7d9e4.png

11. בדיקת צינור עיבוד הנתונים

צינור העיבוד של התמונות מוכן לקבל אירועים מ-Cloud Storage. כדי לבדוק את צינור הנתונים, מעלים תמונה לקטגוריית הקלט:

gsutil cp beach.jpg gs://$BUCKET1

מיד אחרי העלאת התמונה, אמורה להופיע הפעלה של Workflows במצב פעיל:

2c914341950b5fde.png

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

9abba6c28c51a9b5.png

אם תציגו את התוכן של דלי הפלט, תראו את התמונה שגודלה שונה, את התמונה שגודלה שונה ונוסף לה סימן מים, ואת התוויות של התמונה:

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

כדי לבדוק, אפשר לפתוח את התמונה שגודלה שונה ונוסף לה סימן מים כדי לראות את התוצאה:

46d375cb05a8aae4.jpeg

12. מזל טוב

כל הכבוד, סיימתם את ה-Codelab!

מה נכלל

  • סקירה כללית של Eventarc ו-Workflows
  • איך פורסים שירותי Cloud Functions
  • איך מתזמרים שירותים באמצעות Workflows
  • איך גורמים ל-Workflows להגיב לאירועים ב-Cloud Storage באמצעות Eventarc