תחילת העבודה עם Cloud Functions (דור שני)

1. מבוא

כדי להתחיל לכתוב פונקציות של Cloud Run, תוכלו להיעזר בסדנאות הקוד הבאות:

אחרת, בשיעור ה-Codelab הזה תלמדו איך ליצור פונקציות ב-Cloud Functions (דור שני).

סקירה כללית

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

ב-codelab הזה תלמדו איך ליצור פונקציות של Cloud Functions שמגיבות לקריאות HTTP, ומופעלות על ידי הודעות Pub/Sub ויומני ביקורת של Cloud.

מה חדש?

הגרסה החדשה של Cloud Functions מספקת חוויית FaaS משופרת שמבוססת על Cloud Run, ‏ Cloud Build, ‏ Artifact Registry ו-Eventarc.

תשתית משופרת

  • עיבוד בקשות ארוך יותר: אפשר להריץ את Cloud Functions למשך זמן ארוך יותר מברירת המחדל של 5 דקות, וכך להריץ בקלות עומסי עבודה ארוכים יותר של בקשות, כמו עיבוד של כמויות גדולות של נתונים מ-Cloud Storage או מ-BigQuery. בפונקציות HTTP, הזמן הוא עד 60 דקות. בפונקציות מבוססות-אירועים, כרגע חל פרק זמן של עד 10 דקות.
  • מכונות גדולות יותר: אפשר להשתמש ב-Cloud Functions עם עד 16GB של זיכרון RAM ו-4 מעבדי vCPU, שמאפשרים עומסי עבודה גדולים יותר בזיכרון, עם עומס חישוב גבוה יותר ועם יותר משימות מקבילות.
  • ביצוע בו-זמנית: עיבוד של עד 1,000 בקשות בו-זמנית באמצעות מכונה אחת של פונקציה, כדי לצמצם את הזמן הנדרש להפעלה מחדש ולשפר את זמן האחזור כשמשנים את קנה המידה.
  • מכונות מינימום: כדאי להגדיר מכונות שחוממו מראש כדי לקצר את זמני ההפעלה הראשונית, ולוודא שזמן האתחול של האפליקציה לא משפיע על ביצועי האפליקציה.
  • פיצול תנועה: תמיכה במספר גרסאות של הפונקציות, פיצול התנועה בין גרסאות שונות וחזרה לגרסה קודמת של הפונקציה.

כיסוי נרחב יותר של אירועים ותמיכה ב-CloudEvents

  • שילוב עם Eventarc: Cloud Functions כולל עכשיו תמיכה מקורית ב-Eventarc, שמאפשרת להשתמש ב-יותר מ-90 מקורות אירועים באמצעות יומני הביקורת של Cloud (BigQuery, ‏ Cloud SQL, ‏ Cloud Storage וכו'). כמובן ש-Cloud Functions עדיין תומך באירועים ממקורות מותאמים אישית, על ידי פרסום ישירות ב-Cloud Pub/Sub.
  • פורמט CloudEvent: כל הפונקציות מבוססות-האירועים פועלות בהתאם לתקן CloudEvents ( cloudevents.io) של התחום, ללא קשר למקור, כדי להבטיח חוויית פיתוח עקבית. עומסי העבודה נשלחים באמצעות אירוע CloudEvent מובנה עם עומסי עבודה מסוג cloudevent.data, ומיישמים את תקן CloudEvent.

מה תלמדו

  • סקירה כללית על Cloud Functions (דור שני).
  • איך לכתוב פונקציה שתגיב לשיחות HTTP.
  • איך לכתוב פונקציה שמגיבה להודעות Pub/Sub.
  • איך כותבים פונקציה שמגיבה לאירועים ב-Cloud Storage.
  • איך כותבים פונקציה שמגיבה ליומני הביקורת של Cloud.
  • איך לחלק את התנועה בין שתי גרסאות.
  • איך להיפטר מהפעלה במצב התחלתי (cold start) באמצעות מכונות מינימליות.
  • איך מגדירים בו-זמניות.

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

הגדרת סביבה בקצב אישי

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

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

הפעלת Cloud Shell

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

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

55efc1aaa7a4d3ad.png

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

7ffe5cbb04455448.png

המכונה הווירטואלית הזו כוללת את כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, משפרת מאוד את ביצועי הרשת ואת האימות. אתם יכולים לבצע את כל העבודה בקודלאב הזה בדפדפן. אין צורך להתקין שום דבר.

הגדרת gcloud

ב-Cloud Shell, מוודאים שמזהה הפרויקט מוגדר ונשמר במשתנה PROJECT_ID ושהערך של REGION מוגדר כ-us-west1:

gcloud config set project [YOUR-PROJECT-ID]
PROJECT_ID=$(gcloud config get-value project)
REGION=us-west1

הפעלת ממשקי API

מפעילים את כל השירותים הנדרשים:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudfunctions.googleapis.com \
  cloudbuild.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com \
  logging.googleapis.com \
  pubsub.googleapis.com

3. פונקציית HTTP

בפונקציה הראשונה, נוצר פונקציית Node.js מאומתת שמגיבה לבקשות HTTP. נשתמש גם בזמן קצוב לתפוגה של 10 דקות כדי להמחיש איך אפשר לתת לפונקציה יותר זמן להגיב לבקשות HTTP.

יצירה

יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:

mkdir ~/hello-http && cd $_

יוצרים קובץ index.js שמגיב פשוט לבקשות HTTP:

const functions = require('@google-cloud/functions-framework');

functions.http('helloWorld', (req, res) => {
  res.status(200).send('HTTP with Node.js in GCF 2nd gen!');
});

יוצרים קובץ package.json כדי לציין את יחסי התלות:

{
  "name": "nodejs-functions-gen2-codelab",
  "version": "0.0.1",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^2.0.0"
  }
}

פריסה

פורסים את הפונקציה:

gcloud functions deploy nodejs-http-function \
  --gen2 \
  --runtime nodejs16 \
  --entry-point helloWorld \
  --source . \
  --region $REGION \
  --trigger-http \
  --timeout 600s

למרות שזה לא הכרחי בשלב הזה, חשוב לשים לב למכסת הזמן של 600 שניות. כך לפונקציה תהיה זמן קצוב ארוך יותר להגיב לבקשות HTTP.

אחרי הפריסה, תוכלו לראות את הפונקציה בקטע Cloud Functions במסוף Cloud:

7541800e1e3f299f.png

בדיקה

בודקים את הפונקציה באמצעות הפקודה הבאה:

gcloud functions call nodejs-http-function \
  --gen2 --region $REGION

התשובה אמורה להיות ההודעה HTTP with Node.js in GCF 2nd gen!.

4. פונקציית Pub/Sub

בפונקציה השנייה, נגדיר פונקציית Python שתופעל על ידי הודעת Pub/Sub שפורסמה בנושא ספציפי.

הגדרת אסימוני אימות של Pub/Sub

אם הפעלתם את חשבון השירות של Pub/Sub ב-8 באפריל 2021 או לפני כן, מקצים את התפקיד iam.serviceAccountTokenCreator לחשבון השירות של Pub/Sub:

PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member  serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

יצירה

יוצרים נושא Pub/Sub לשימוש בדוגמה:

TOPIC=cloud-functions-gen2-topic
gcloud pubsub topics create $TOPIC

יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:

mkdir ~/hello-pubsub && cd $_

יוצרים קובץ main.py שמתעדה פשוט הודעה שמכילה את מזהה האירוע ב-Cloud:

import functions_framework

@functions_framework.cloud_event
def hello_pubsub(cloud_event):
   print('Pub/Sub with Python in GCF 2nd gen! Id: ' + cloud_event['id'])

יוצרים קובץ requirements.txt עם התוכן הבא כדי לציין את יחסי התלות:

functions-framework==3.*

פריסה

פורסים את הפונקציה:

gcloud functions deploy python-pubsub-function \
  --gen2 \
  --runtime python39 \
  --entry-point hello_pubsub \
  --source . \
  --region $REGION \
  --trigger-topic $TOPIC

אחרי הפריסה, תוכלו לראות את הפונקציה בקטע Cloud Functions במסוף Cloud:

107029714c32baff.png

בדיקה

כדי לבדוק את הפונקציה, שולחים הודעה לנושא:

gcloud pubsub topics publish $TOPIC --message="Hello World"

ה-CloudEvent שהתקבל אמור להופיע ביומן:

gcloud functions logs read python-pubsub-function \
  --region $REGION --gen2 --format "value(log)"

5. Cloud Storage Function

בפונקציה הבאה נשתמש ב-Node.js כדי ליצור פונקציה שתגיב לאירועים מקטגוריה של Cloud Storage.

הגדרה

כדי להשתמש בפונקציות של Cloud Storage, מקצים לחשבון השירות של Cloud Storage את התפקיד pubsub.publisher ב-IAM:

SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT \
  --role roles/pubsub.publisher

יצירה

יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:

mkdir ~/hello-storage && cd $_

יוצרים קובץ index.js שמגיב לאירועים ב-Cloud Storage:

const functions = require('@google-cloud/functions-framework');

functions.cloudEvent('helloStorage', (cloudevent) => {
  console.log('Cloud Storage event with Node.js in GCF 2nd gen!');
  console.log(cloudevent);
});

יוצרים קובץ package.json כדי לציין את יחסי התלות:

{
  "name": "nodejs-functions-gen2-codelab",
  "version": "0.0.1",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^2.0.0"
  }
}

פריסה

קודם כול יוצרים קטגוריה ב-Cloud Storage (או משתמשים בקטגוריה קיימת שכבר יש לכם):

​​export BUCKET="gs://gcf-gen2-storage-$PROJECT_ID"
gsutil mb -l $REGION $BUCKET

פורסים את הפונקציה:

gcloud functions deploy nodejs-storage-function \
  --gen2 \
  --runtime nodejs16 \
  --entry-point helloStorage \
  --source . \
  --region $REGION \
  --trigger-bucket $BUCKET \
  --trigger-location $REGION

אחרי הפריסה, תוכלו לראות את הפונקציה בקטע Cloud Functions במסוף Cloud.

בדיקה

כדי לבדוק את הפונקציה, מעלים קובץ לקטגוריה:

echo "Hello World" > random.txt
gsutil cp random.txt $BUCKET/random.txt

ה-CloudEvent שהתקבל אמור להופיע ביומן:

gcloud functions logs read nodejs-storage-function \
  --region $REGION --gen2 --limit=100 --format "value(log)"

6. פונקציה של יומני הביקורת של Cloud

בפונקציה הבאה נשתמש ב-Node.js כדי ליצור אירוע ביומן הביקורת של Cloud כשיוצרים מכונה וירטואלית ב-Compute Engine. בתגובה, המערכת מוסיפה תווית למכונה הווירטואלית החדשה שנוצרה, ומציינת את היוצר של המכונה הווירטואלית.

איך בודקים אילו מכונות וירטואליות חדשות נוצרו ב-Compute Engine

כשמכונת VM נוצרת, ‏Compute Engine יוצרת 2 יומני ביקורת.

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

8d394a481644c4b6.png

ההודעה השנייה מונפקת אחרי יצירת המכונה הווירטואלית, והיא נראית כך:

ee0e221d82887cd1.png

שימו לב לשדה operation עם הערכים first: true ו-last: true. יומן הביקורת השני מכיל את כל המידע שנחוץ לנו כדי לתייג מכונה, לכן נשתמש בדגל last: true כדי לזהות אותו ב-Cloud Functions.

הגדרה

כדי להשתמש בפונקציות של יומני הביקורת של Cloud, צריך להפעיל את יומני הביקורת ב-Eventarc. צריך גם להשתמש בחשבון שירות עם התפקיד eventarc.eventReceiver.

  1. מפעילים את יומני הביקורת של Cloud מסוגים קריאת אדמין, קריאת נתונים וכתיבת נתונים עבור Compute Engine API:

76b7417ea4071241.png

  1. מקצים לחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine את התפקיד eventarc.eventReceiver ב-IAM:
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
  --role roles/eventarc.eventReceiver

קבל את הקוד

משכפלים את המאגר שמכיל את האפליקציה:

git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git

מנווטים לספריית האפליקציות:

cd eventarc-samples/gce-vm-labeler/gcf/nodejs

הקובץ index.js מכיל את קוד האפליקציה שמקבל את יומן הביקורת בתוך CloudEvent. לאחר מכן, הקוד מחלץ את פרטי המכונה הווירטואלית ב-Compute Engine ומגדיר תווית למכונה הווירטואלית. מומלץ לקרוא מידע נוסף על index.js בעצמך.

פריסה

אפשר לפרוס את הפונקציה באמצעות gcloud כמו בעבר. שימו לב שהפונקציה מסננת את יומני הביקורת של הוספות ב-Compute Engine באמצעות הדגל --trigger-event-filters:

gcloud functions deploy gce-vm-labeler \
  --gen2 \
  --runtime nodejs16 \
  --entry-point labelVmCreation \
  --source . \
  --region $REGION \
  --trigger-event-filters="type=google.cloud.audit.log.v1.written,serviceName=compute.googleapis.com,methodName=beta.compute.instances.insert" \
  --trigger-location us-central1

אפשר גם לפרוס את הפונקציה ולהוסיף טריגר של Eventarc דרך מסוף Google Cloud.

קודם עוברים לקטע Cloud Functions ויוצרים פונקציה עם סביבה מדור שני:

8ba79a12ee152d8.png

לוחצים על הלחצן Add Eventarc Trigger:

655346320a5e3631.png

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

בוחרים את ספק האירועים ואת האירוע הרצוי ולוחצים על Save Trigger:

7d24325ff06c9b05.png

לבסוף, בדף הבא אפשר לעדכן את הקבצים index.js ו-package.json באמצעות הקבצים index.js ו-package.json ב-GitHub, וללחוץ על הלחצן Deploy:

f2e338eed2ccf5a2.png

בדיקה

כדי לבדוק את הפונקציה של יומן הביקורת, צריך ליצור מכונה וירטואלית של Compute Engine במסוף Cloud (אפשר גם ליצור מכונות וירטואליות באמצעות gcloud, אבל נראה שהן לא יוצרות יומני ביקורת).

עוברים לקטע Compute Engine > VM instances במסוף Cloud ויוצרים מכונה וירטואלית חדשה. בסיום יצירת המכונה הווירטואלית, התווית creator שהוספתם אמורה להופיע במכונה הווירטואלית במסוף Cloud בקטע Basic information (מידע בסיסי), או באמצעות הפקודה הבאה:

gcloud compute instances describe YOUR_VM_NAME

התווית אמורה להופיע בפלט, כמו בדוגמה הבאה:

...
labelFingerprint: ULU6pAy2C7s=
labels:
  creator: atameldev
...

7. חלוקת תנועה

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

בשלב הזה, תפרסו 2 גרסאות של פונקציה ואז תחלקו את התנועה ביניהן ביחס של 50-50.

יצירה

יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:

mkdir ~/traffic-splitting && cd $_

יוצרים קובץ main.py עם פונקציית Python שקוראת משתנה סביבה של צבע ומחזירה Hello World בצבע הרקע הזה:

import os

color = os.environ.get('COLOR')

def hello_world(request):
    return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'

פריסה

פורסים את הגרסה הראשונה של הפונקציה עם רקע כתום:

COLOR=orange
gcloud functions deploy hello-world-colored \
  --gen2 \
  --runtime python39 \
  --entry-point hello_world \
  --source . \
  --region $REGION \
  --trigger-http \
  --allow-unauthenticated \
  --update-env-vars COLOR=$COLOR

בשלב הזה, אם בודקים את הפונקציה על ידי הצגת הטריגר של ה-HTTP (פלט ה-URI של פקודת הפריסה שלמעלה) בדפדפן, אמור להופיע Hello World עם רקע כתום:

36ca0c5f39cc89cf.png

פורסים את הגרסה השנייה עם רקע צהוב:

COLOR=yellow
gcloud functions deploy hello-world-colored \
  --gen2 \
  --runtime python39 \
  --entry-point hello_world \
  --source . \
  --region $REGION \
  --trigger-http \
  --allow-unauthenticated \
  --update-env-vars COLOR=$COLOR

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

391286a08ad3cdde.png

חלוקת התנועה ביחס של 50-50

כדי לפצל את התנועה בין הגרסאות הכתומה והצהובה, צריך למצוא את מזהי הגרסאות של שירותי Cloud Run הבסיסיים. זו הפקודה להצגת מזהי הגרסאות:

gcloud run revisions list --service hello-world-colored \
  --region $REGION --format 'value(REVISION)'

הפלט אמור להיראות כך:

hello-world-colored-00001-man
hello-world-colored-00002-wok

עכשיו צריך לפצל את התנועה בין שתי הגרסאות הבאות באופן הבא (מעדכנים את X-XXX בהתאם לשמות הגרסאות):

gcloud run services update-traffic hello-world-colored \
  --region $REGION \
  --to-revisions hello-world-colored-0000X-XXX=50,hello-world-colored-0000X-XXX=50

בדיקה

כדי לבדוק את הפונקציה, נכנסים לכתובת ה-URL הציבורית שלה. חצי מהזמן אמורה להופיע הגרסה הכתומה, ובחצי השני אמורה להופיע הגרסה הצהובה:

36ca0c5f39cc89cf.png 391286a08ad3cdde.png

מידע נוסף זמין במאמר החזרות לאחור, השקות הדרגתיות והעברת תנועה.

8. מספר מינימלי של מכונות

ב-Cloud Functions (דור שני), אפשר לציין מספר מינימלי של מכונות פונקציה שיישמרו במצב 'מוכנות לפעולה' ויהיה אפשר להשתמש בהן כדי למלא בקשות. האפשרות הזו שימושית להגבלת מספר ההפעלות הראשוניות.

בשלב הזה, תפרסו פונקציה עם אתחול איטי. תוכלו לראות את הבעיה של ההפעלה במצב התחלתי (cold start). לאחר מכן, תפרסו את הפונקציה עם ערך המכונה המינימלי שמוגדר כ-1 כדי להיפטר מזמן ההפעלה הראשונית.

יצירה

יוצרים תיקייה לאפליקציה ועוברים אליה:

mkdir ~/min-instances && cd $_

יוצרים קובץ main.go. לשירות Go הזה יש פונקציית init שנכנסת למצב שינה למשך 10 שניות כדי לדמות אתחול ארוך. יש לו גם פונקציה HelloWorld שמגיבה לשיחות HTTP:

package p

import (
        "fmt"
        "net/http"
        "time"
)

func init() {
        time.Sleep(10 * time.Second)
}

func HelloWorld(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Slow HTTP Go in GCF 2nd gen!")
}

פריסה

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

gcloud functions deploy slow-function \
  --gen2 \
  --runtime go116 \
  --entry-point HelloWorld \
  --source . \
  --region $REGION \
  --trigger-http \
  --allow-unauthenticated

בודקים את הפונקציה באמצעות הפקודה הבאה:

gcloud functions call slow-function \
  --gen2 --region $REGION

בשיחה הראשונה תהיה עיכוב של 10 שניות (הפעלה קרה), ולאחר מכן תוצג ההודעה. שיחות חוזרות אמורות להתקבל באופן מיידי.

הגדרת מספר מינימלי של מכונות

כדי להימנע מהפעלה מחדש (cold start) בבקשה הראשונה, צריך לפרוס מחדש את הפונקציה עם הדגל --min-instances מוגדר ל-1 באופן הבא:

gcloud functions deploy slow-function \
  --gen2 \
  --runtime go116 \
  --entry-point HelloWorld \
  --source . \
  --region $REGION \
  --trigger-http \
  --allow-unauthenticated \
  --min-instances 1

בדיקה

בודקים שוב את הפונקציה:

gcloud functions call slow-function \
  --gen2 --region $REGION

עיכוב של 10 שניות לא אמור להופיע יותר בבקשה הראשונה. הבעיה של זמן האתחול הראשוני בקריאה הראשונה (אחרי זמן רב ללא קריאה) נפתרה, בזכות מכונות מינימום!

מידע נוסף זמין במאמר שימוש במספר מינימלי של מכונות.

9. בו-זמניות

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

בשלב הזה, תשתמשו בפונקציה עם אתחול איטי מהשלב הקודם. תשלחו אליה 10 בקשות ותבחינו שוב בבעיה של הפעלה מחדש, כי צריך ליצור מכונות פונקציה חדשות כדי לטפל בבקשות.

כדי לפתור את הבעיה של הפעלה מחדש, תפרסו פונקציה אחרת עם ערך בו-זמניות של 100. תוכלו לראות עכשיו שה-10 בקשות לא גורמות לבעיה של הפעלה מחדש (cold start), ושמכונה אחת של פונקציה יכולה לטפל בכל הבקשות.

בדיקה ללא בו-זמניות

מקבלים את כתובת ה-URL של הפונקציה:

SLOW_URL=$(gcloud functions describe slow-function --region $REGION --gen2 --format="value(serviceConfig.uri)")

משתמשים בכלי למדידת ביצועים בקוד פתוח שנקרא hey כדי לשלוח 10 בקשות בו-זמנית לפונקציה האיטית. hey כבר מותקן ב-Cloud Shell:

hey -n 10 -c 10 $SLOW_URL

בפלט של hey אמור להופיע שהטיפול בחלק מהבקשות נמשך זמן רב:

Summary:
  Total:        10.9053 secs
  Slowest:      10.9048 secs
  Fastest:      0.4439 secs
  Average:      9.7930 secs
  Requests/sec: 0.9170

  Total data:   310 bytes
  Size/request: 31 bytes

Response time histogram:
  0.444 [1]     |■■■■
  1.490 [0]     |
  2.536 [0]     |
  3.582 [0]     |
  4.628 [0]     |
  5.674 [0]     |
  6.720 [0]     |
  7.767 [0]     |
  8.813 [0]     |
  9.859 [0]     |
  10.905 [9]    |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

הסיבה לכך היא שנוצרות יותר מכונות של פונקציות כדי לטפל בבקשות. אם בודקים את מספר המכונות הפעילות של הפונקציה, צריך לראות גם שנוצרו כמה מכונות בשלב מסוים והן גורמות לבעיה של הפעלה מחדש (cold start):

9f5c6877836d62fb.png

פריסה

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

gcloud functions deploy slow-concurrent-function \
  --gen2 \
  --runtime go116 \
  --entry-point HelloWorld \
  --source . \
  --region $REGION \
  --trigger-http \
  --allow-unauthenticated \
  --min-instances 1

הגדרת בו-זמניות

מגדירים את רמת הסימולטניות של שירות Cloud Run הבסיסי של הפונקציה ל-100 (הערך המקסימלי הוא 1,000). כך אפשר להבטיח שאפשר לטפל ב-100 בקשות לפחות במכונה אחת של פונקציה:

gcloud run services update slow-concurrent-function \
  --concurrency 100 \
  --cpu 1 \
  --region $REGION 

בדיקה עם בו-זמניות

מקבלים את כתובת ה-URL של הפונקציה:

SLOW_CONCURRENT_URL=$(gcloud functions describe slow-concurrent-function --region $REGION --gen2 --format="value(serviceConfig.uri)")

לאחר מכן, משתמשים ב-hey כדי לשלוח 10 בקשות בו-זמנית:

hey -n 10 -c 10 $SLOW_CONCURRENT_URL

בפלט של hey אמור להופיע שהבקשות מטופלות במהירות:

Summary:
  Total:        0.2164 secs
  Slowest:      0.2163 secs
  Fastest:      0.0921 secs
  Average:      0.2033 secs
  Requests/sec: 46.2028

  Total data:   310 bytes
  Size/request: 31 bytes

Response time histogram:
  0.092 [1]     |■■■■
  0.105 [0]     |
  0.117 [0]     |
  0.129 [0]     |
  0.142 [0]     |
  0.154 [0]     |
  0.167 [0]     |
  0.179 [0]     |
  0.191 [0]     |
  0.204 [0]     |
  0.216 [9]     |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

מכונה אחת של פונקציה הצליחה לטפל בכל הבקשות, ובעיית ההפעלה הראשונית נעלמה, בזכות העלייה ביכולת לבצע פעולות בו-זמנית.

מידע נוסף זמין במאמר ביצוע בו-זמנית.

10. מעולה!

כל הכבוד על השלמת ה-Codelab!

מה עסקנו בו

  • סקירה כללית על Cloud Functions (דור שני).
  • איך לכתוב פונקציה שתגיב לשיחות HTTP.
  • איך לכתוב פונקציה שמגיבה להודעות Pub/Sub.
  • איך כותבים פונקציה שמגיבה לאירועים ב-Cloud Storage.
  • איך כותבים פונקציה שמגיבה ליומני הביקורת של Cloud.
  • איך לחלק את התנועה בין שתי גרסאות.
  • איך להיפטר מהפעלה במצב התחלתי (cold start) באמצעות מכונות מינימליות.
  • איך מגדירים בו-זמניות.