1. סקירה כללית
מטרת סדרת ה-codelabs של Serverless Migration Station (הדרכות מעשיות בקצב אישי) והסרטונים שקשורים אליה היא לעזור למפתחים של Google Cloud Serverless לחדש את האפליקציות שלהם. לשם כך, הם מקבלים הדרכה לגבי העברה אחת או יותר, בעיקר מעבר משירותים מדור קודם. כך האפליקציות שלכם יהיו ניידות יותר, ותקבלו יותר אפשרויות וגמישות. תוכלו לשלב את האפליקציות עם מגוון רחב יותר של מוצרי Cloud ולגשת אליהם, ולשדרג בקלות רבה יותר לגרסאות חדשות יותר של השפה. הסדרה הזו מתמקדת בהתחלה במשתמשי הענן הראשונים, בעיקר מפתחים של App Engine (סביבה רגילה), אבל היא רחבה מספיק כדי לכלול פלטפורמות אחרות של Serverless כמו Cloud Functions ו-Cloud Run, או במקומות אחרים אם רלוונטי.
מטרת ה-codelab הזה היא להעביר את אפליקציית הדוגמה של מודול 8 ל-Python 3, וגם להחליף את הגישה ל-Datastore (Cloud Firestore במצב Datastore) משימוש ב-Cloud NDB לשימוש בספריית הלקוח המקורית של Cloud Datastore ולשדרג לגרסה האחרונה של ספריית הלקוח של Cloud Tasks.
הוספנו שימוש בתור משימות למשימות push במודול 7, ואז העברנו את השימוש הזה ל-Cloud Tasks במודול 8. במודול 9, אנחנו ממשיכים ל-Python 3 ול-Cloud Datastore. משתמשים בתורי משימות לביצוע משימות משיכה יבצעו מיגרציה ל-Cloud Pub/Sub, ויצטרכו לעיין במודולים 18-19.
כאן אפשר להבין איך
- העברה של האפליקציה לדוגמה ממודול 8 ל-Python 3
- מעבר מגישה ל-Datastore דרך Cloud NDB לגישה דרך ספריות הלקוח של Cloud Datastore
- שדרוג לגרסה העדכנית ביותר של ספריית הלקוח של Cloud Tasks
הדרישות
- פרויקט ב-Google Cloud Platform עם חשבון לחיוב פעיל ב-GCP
- מיומנויות בסיסיות ב-Python
- ידע מעשי בפקודות נפוצות של Linux
- ידע בסיסי בפיתוח ופריסה של אפליקציות App Engine
- אפליקציית App Engine תקינה של מודול 8: מומלץ להשלים את ה-codelab של מודול 8 או להעתיק את האפליקציה של מודול 8 מהמאגר
סקר
איך תשתמשו במדריך הזה?
איך היית מדרג את חוויית השימוש שלך ב-Python?
איזה דירוג מתאים לדעתך לחוויית השימוש שלך בשירותי Google Cloud?
2. רקע
מודול 7 מראה איך להשתמש במשימות push של App Engine Task Queue באפליקציות Python 2 Flask App Engine. במודול 8, מעבירים את האפליקציה מ-Task Queue ל-Cloud Tasks. במודול 9 ממשיכים את המסע הזה ומבצעים היסב של האפליקציה ל-Python 3, וגם משנים את הגישה למאגר הנתונים משימוש ב-Cloud NDB לשימוש בספריית הלקוח המקורית של Cloud Datastore.
מכיוון ש-Cloud NDB פועל גם עם Python 2 וגם עם Python 3, הוא מתאים למשתמשי App Engine שמעבירים את האפליקציות שלהם מ-Python 2 ל-Python 3. מיגרציה נוספת של ספריות לקוח ל-Cloud Datastore היא אופציונלית לחלוטין, ויש רק סיבה אחת לשקול אותה: יש לכם אפליקציות שאינן App Engine (או אפליקציות Python 3 App Engine) שכבר משתמשות בספריית הלקוח של Cloud Datastore, ואתם רוצים לאחד את בסיס הקוד שלכם כדי לגשת ל-Datastore באמצעות ספריית לקוח אחת בלבד. Cloud NDB נוצר במיוחד עבור מפתחי Python 2 App Engine ככלי להעברה ל-Python 3, כך שאם עדיין אין לכם קוד שמשתמש בספריית הלקוח Cloud Datastore, אתם לא צריכים לשקול את ההעברה הזו.
לבסוף, הפיתוח של ספריית הלקוח של Cloud Tasks ממשיך רק ב-Python 3, ולכן אנחנו 'מעבירים' מאחת מגרסאות Python 2 האחרונות לגרסה המקבילה שלה ב-Python 3. למזלכם, אין שינויים שעלולים לשבור את התאימות מ-Python 2, כך שאין שום דבר נוסף שאתם צריכים לעשות.
במדריך הזה נסביר איך:
- הגדרה/עבודה מקדימה
- עדכון ההגדרות
- שינוי קוד האפליקציה
3. הגדרה/עבודה מקדימה
בקטע הזה נסביר איך:
- הגדרת פרויקט בענן
- קבלת אפליקציה לדוגמה של ערך בסיס
- (Re)Deploy and validate baseline app
השלבים האלה מבטיחים שתתחילו עם קוד תקין ושהוא יהיה מוכן להעברה לשירותי ענן.
1. הגדרת פרויקט
אם השלמתם את ה-Codelab של מודול 8, תוכלו להשתמש שוב באותו פרויקט (ובאותו קוד). אפשר גם ליצור פרויקט חדש לגמרי או להשתמש מחדש בפרויקט קיים אחר. צריך לוודא שלפרויקט יש חשבון לחיוב פעיל ואפליקציית App Engine מופעלת. כדאי למצוא את מזהה הפרויקט כי תצטרכו אותו במהלך ה-codelab הזה, ותצטרכו להשתמש בו בכל פעם שתיתקלו במשתנה PROJECT_ID.
2. קבלת אפליקציה לדוגמה של ערך בסיס
אחד מהתנאים המוקדמים הוא אפליקציית App Engine תקינה של מודול 8: מומלץ להשלים את ה-codelab של מודול 8 או להעתיק את האפליקציה של מודול 8 מהמאגר. בין אם אתם משתמשים בקוד שלכם או בקוד שלנו, נתחיל בקוד של מודול 8 ('START'). ב-codelab הזה מוסבר איך לבצע את ההעברה, ובסופו מוצג קוד שדומה למה שמופיע בתיקיית המאגר של מודול 9 (FINISH).
- התחלה: מאגר מודול 8
- סיום: Module 9 repo
- מאגר שלם (שיבוט או הורדה של קובץ ZIP)
לא משנה באיזו אפליקציה של מודול 7 אתם משתמשים, התיקייה צריכה להיראות כמו בדוגמה הבאה, ואולי גם לכלול את התיקייה lib:
$ ls README.md appengine_config.py requirements.txt app.yaml main.py templates
3. (Re)Deploy and validate baseline app
כדי לפרוס את האפליקציה של מודול 8:
- אם יש תיקייה בשם
lib, מוחקים אותה ומריצים את הפקודהpip install -t lib -r requirements.txtכדי לאכלס מחדש אתlib. יכול להיות שתצטרכו להשתמש ב-pip2במקום זאת אם גם Python 2 וגם Python 3 מותקנים במחשב הפיתוח שלכם. - מוודאים שהתקנתם והפעלתם את כלי שורת הפקודה
gcloud, ובדקתם את השימוש בו. - (אופציונלי) מגדירים את פרויקט בענן באמצעות
gcloud config set projectPROJECT_IDאם לא רוצים להזין אתPROJECT_IDבכל פקודתgcloudשמריצים. - פריסת האפליקציה לדוגמה באמצעות
gcloud app deploy - מוודאים שהאפליקציה פועלת כמו שצריך ללא בעיות. אם השלמתם את ה-codelab של מודול 8, האפליקציה מציגה את המבקרים המובילים יחד עם הביקורים האחרונים (כפי שמוצג בהמשך). בתחתית המסך מופיע סימון של המשימות הישנות יותר שיימחקו.

4. עדכון ההגדרות
requirements.txt
הנוסחה החדשה requirements.txt כמעט זהה לנוסחה של מודול 8, עם שינוי גדול אחד בלבד: מחליפים את google-cloud-ndb ב-google-cloud-datastore. צריך לבצע את השינוי הזה כך שהקובץ requirements.txt ייראה כך:
flask
google-cloud-datastore
google-cloud-tasks
בקובץ requirements.txt הזה לא מופיעים מספרי גרסאות, ולכן הגרסאות העדכניות ביותר נבחרות. אם מתגלות בעיות תאימות, נהוג להשתמש במספרי גרסאות כדי לנעול גרסאות תקינות של אפליקציה.
app.yaml
זמן הריצה של App Engine מהדור השני לא תומך בספריות מובנות של צד שלישי כמו בגרסה 2.x, וגם לא בהעתקה של ספריות לא מובנות. הדרישה היחידה לחבילות של צד שלישי היא לפרט אותן ב-requirements.txt. לכן אפשר למחוק את כל הקטע libraries של app.yaml.
עדכון נוסף הוא שזמן הריצה של Python 3 מחייב שימוש במסגרות אינטרנט שמבצעות ניתוב משלהן. כתוצאה מכך, צריך לשנות את כל המטפלים בסקריפטים ל-auto. עם זאת, מכיוון שצריך לשנות את כל הנתיבים ל-auto, ואין קבצים סטטיים שמוגשים מאפליקציית הדוגמה הזו, אין טעם להשתמש ב-handlers כלשהם, ולכן צריך להסיר גם את הקטע handlers כולו.
הדבר היחיד שצריך לעשות ב-app.yaml הוא להגדיר את זמן הריצה לגרסה נתמכת של Python 3, למשל 3.10. תבצע את השינוי הזה כך שהקיצור החדש של app.yaml יהיה רק השורה הבודדת הזו:
runtime: python310
מחיקת הקובץ appengine_config.py והספרייה lib
הדור הבא של סביבות זמן ריצה ב-App Engine משפר את השימוש בחבילות צד שלישי:
- ספריות מובנות הן ספריות שנבדקו על ידי Google והועמדו לרשותכם בשרתי App Engine, כנראה כי הן מכילות קוד C/C++ שמפתחים לא יכולים לפרוס בענן – הן כבר לא זמינות בסביבות זמן הריצה מהדור השני.
- אין יותר צורך להעתיק ספריות שאינן מוכללות (לפעמים נקראות 'יצירת עותק מקוד של צד שלישי (vendoring)' או 'איגוד עצמי') בסביבות זמן ריצה מהדור השני. במקום זאת, צריך לפרט אותם ב-
requirements.txt, שם מערכת ה-Build מתקינה אותם באופן אוטומטי בשמכם בזמן הפריסה.
בעקבות השינויים האלה בניהול חבילות של צד שלישי, אין יותר צורך בקובץ appengine_config.py או בתיקייה lib, ולכן צריך למחוק אותם. בזמן ריצה מהדור השני, App Engine מתקין באופן אוטומטי חבילות של צד שלישי שמופיעות ב-requirements.txt. סיכום:
- אין ספריות של צד שלישי שצורפו או הועתקו; יש לציין אותן ב-
requirements.txt - אין
pip installבתיקייהlib, כלומר אין תיקייהlibבכלל - אין ספריות מובנות של צד שלישי (ולכן אין קטע
libraries) ב-app.yaml; צריך לפרט אותן ב-requirements.txt - אם אין ספריות של צד שלישי שאפשר להפנות אליהן מהאפליקציה, לא יהיה קובץ
appengine_config.py
הדרישה היחידה למפתחים היא לפרט את כל הספריות הרצויות של צד שלישי ב-requirements.txt.
5. עדכון קובצי אפליקציות
יש רק קובץ בקשה אחד, main.py, ולכן כל השינויים בקטע הזה משפיעים רק על הקובץ הזה. בהמשך מוצגת דוגמה לשינויים הנדרשים כדי לשכתב את הקוד הקיים לאפליקציה החדשה. לא צריך לקרוא את הקוד שורה אחר שורה, כי המטרה היא רק לקבל סקירה כללית של מה שנדרש בשכתוב הזה (אבל אפשר לפתוח אותו בכרטיסייה חדשה או להוריד אותו ולהגדיל אותו אם רוצים).

עדכון ייבוא והפעלה
בקטע הייבוא ב-main.py של מודול 8 נעשה שימוש ב-Cloud NDB וב-Cloud Tasks. הוא אמור להיראות כך:
לפני:
from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, tasks
app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()
הרישום ביומן פשוט יותר ומשופר בסביבות זמן הריצה מהדור השני, כמו Python 3:
- לשימוש ביומנים מקיפים, כדאי להשתמש ב-Cloud Logging
- כדי לשלוח יומן פשוט, פשוט שולחים לכתובת
stdout(אוstderr) דרךprint() - אין צורך להשתמש במודול Python
logging(לכן צריך להסיר אותו)
לכן, צריך למחוק את הייבוא של logging ולהחליף את google.cloud.ndb ב-google.cloud.datastore. באופן דומה, צריך לשנות את ds_client כך שיצביע על לקוח Datastore במקום על לקוח NDB. אחרי השינויים האלה, החלק העליון של האפליקציה החדשה ייראה כך:
אחרי:
from datetime import datetime
import json
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import datastore, tasks
app = Flask(__name__)
ds_client = datastore.Client()
ts_client = tasks.CloudTasksClient()
מעבר ל-Cloud Datastore
עכשיו הגיע הזמן להחליף את השימוש בספריית הלקוח NDB ב-Datastore. גם App Engine NDB וגם Cloud NDB דורשים מודל נתונים (class). באפליקציה הזו, המודל הוא Visit. הפונקציה store_visit() פועלת באופן זהה בכל שאר מודולי ההעברה: היא רושמת ביקור על ידי יצירת רשומה חדשה של Visit, ושומרת את כתובת ה-IP של הלקוח המבקר ואת סוכן המשתמש (סוג הדפדפן).
לפני:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
אבל ב-Cloud Datastore לא משתמשים במחלקה של מודל נתונים, לכן צריך למחוק את המחלקה. בנוסף, Cloud Datastore לא יוצר באופן אוטומטי חותמת זמן כשנוצרים רשומות, ולכן צריך לעשות זאת באופן ידני באמצעות הקריאה datetime.now().
ללא מחלקת הנתונים, הפונקציה store_visit() ששיניתם אמורה להיראות כך:
אחרי:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
פונקציית המקש היא fetch_visits(). הוא לא רק מבצע את השאילתה המקורית לגבי Visits האחרונים, אלא גם מאחזר את חותמת הזמן של Visit האחרון שמוצג ויוצר את משימת הדחיפה שקוראת ל-/trim (כלומר trim()) כדי למחוק בכמות גדולה את Visits הישנים. כך משתמשים בו ב-Cloud NDB:
לפני:
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
with ds_client.context():
data = Visit.query().order(-Visit.timestamp).fetch(limit)
oldest = time.mktime(data[-1].timestamp.timetuple())
oldest_str = time.ctime(oldest)
logging.info('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
ts_client.create_task(parent=QUEUE_PATH, task=task)
return (v.to_dict() for v in data), oldest_str
השינויים העיקריים:
- מחליפים את השאילתה של Cloud NDB בשאילתה המקבילה של Cloud Datastore. יש הבדלים קלים בסגנונות השאילתות.
- ב-Datastore לא צריך להשתמש במנהל הקשר ולא צריך לחלץ את הנתונים (עם
to_dict()) כמו ב-Cloud NDB. - החלפת רישום שיחות ב-
print()
אחרי השינויים האלה, fetch_visits() נראה כך:
אחרי:
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
visits = list(query.fetch(limit=limit))
oldest = time.mktime(visits[-1]['timestamp'].timetuple())
oldest_str = time.ctime(oldest)
print('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
בדרך כלל זה כל מה שצריך לעשות. לצערנו, יש בעיה אחת מרכזית.
(אולי) יצירת תור חדש (לדחיפה)
במודול 7, הוספנו שימוש ב-App Engine taskqueue לאפליקציה הקיימת במודול 1. אחד היתרונות המרכזיים של משימות push כתכונה מדור קודם של App Engine הוא שנוצר באופן אוטומטי תור 'ברירת מחדל'. כשביצענו מיגרציה של האפליקציה הזו ל-Cloud Tasks במודול 8, התור הזה כבר היה שם, ולכן עדיין לא היה צורך להתייחס אליו. השינוי הזה מתרחש כאן, במודול 9.
חשוב לזכור שהאפליקציה החדשה ב-App Engine לא משתמשת יותר בשירותי App Engine, ולכן אי אפשר להניח ש-App Engine יוצר באופן אוטומטי תור משימות במוצר אחר (Cloud Tasks). כמו שכתוב, יצירת משימה ב-fetch_visits() (עבור תור שלא קיים) תיכשל. צריך פונקציה חדשה כדי לבדוק אם התור ("default") קיים, ואם לא, ליצור אותו.
קוראים לפונקציה הזו _create_queue_if() ומוסיפים אותה לאפליקציה ממש מעל fetch_visits() כי שם היא נקראת. גוף הפונקציה שרוצים להוסיף:
def _create_queue_if():
'app-internal function creating default queue if it does not exist'
try:
ts_client.get_queue(name=QUEUE_PATH)
except Exception as e:
if 'does not exist' in str(e):
ts_client.create_queue(parent=PATH_PREFIX,
queue={'name': QUEUE_PATH})
return True
הפונקציה create_queue() ב-Cloud Tasks דורשת את נתיב השם המלא של התור למעט שם התור. כדי לפשט את התהליך, יוצרים עוד משתנה PATH_PREFIX שמייצג את QUEUE_PATH פחות שם התור (QUEUE_PATH.rsplit('/', 2)[0]). מוסיפים את ההגדרה שלו קרוב לחלק העליון, כך שבלוק הקוד עם כל הקצאות הקבועים ייראה כך:
_, PROJECT_ID = google.auth.default()
REGION_ID = 'REGION_ID' # replace w/your own
QUEUE_NAME = 'default' # replace w/your own
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION_ID, QUEUE_NAME)
PATH_PREFIX = QUEUE_PATH.rsplit('/', 2)[0]
עכשיו משנים את השורה האחרונה ב-fetch_visits() כדי להשתמש ב-_create_queue_if(). קודם יוצרים את התור אם צריך, ואז יוצרים את המשימה:
if _create_queue_if():
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
הערכים של _create_queue_if() ושל fetch_visits() אמורים להיראות כך אחרי צבירה:
def _create_queue_if():
'app-internal function creating default queue if it does not exist'
try:
ts_client.get_queue(name=QUEUE_PATH)
except Exception as e:
if 'does not exist' in str(e):
ts_client.create_queue(parent=PATH_PREFIX,
queue={'name': QUEUE_PATH})
return True
def fetch_visits(limit):
'get most recent visits & add task to delete older visits'
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
visits = list(query.fetch(limit=limit))
oldest = time.mktime(visits[-1]['timestamp'].timetuple())
oldest_str = time.ctime(oldest)
print('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
if _create_queue_if():
ts_client.create_task(parent=QUEUE_PATH, task=task)
return visits, oldest_str
מלבד הצורך להוסיף את הקוד הנוסף הזה, שאר הקוד של Cloud Tasks נשאר ברובו ללא שינוי מתוך מודול 8. החלק האחרון בקוד שצריך לבדוק הוא ה-task handler.
עדכון (דחיפה) של גורם מטפל במשימות
ב-task handler, trim(), קוד Cloud NDB מבצע שאילתה לגבי ביקורים ישנים יותר מהביקור הכי ישן שמוצג. הוא משתמש בשאילתה עם מפתחות בלבד כדי לזרז את התהליך – למה לאחזר את כל הנתונים אם צריך רק את מזהי הביקורים? אחרי שמקבלים את כל מזהי הביקורים, אפשר למחוק את כולם בבת אחת באמצעות הפונקציה delete_multi() של Cloud NDB.
לפני:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = float(request.get_json().get('oldest'))
with ds_client.context():
keys = Visit.query(
Visit.timestamp < datetime.fromtimestamp(oldest)
).fetch(keys_only=True)
nkeys = len(keys)
if nkeys:
logging.info('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id()) for k in keys)))
ndb.delete_multi(keys)
else:
logging.info(
'No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
בדומה ל-fetch_visits(), רוב השינויים כוללים החלפה של קוד Cloud NDB ב-Cloud Datastore, שינוי של סגנונות השאילתות, הסרה של השימוש במנהל ההקשר ושינוי של קריאות היומן ל-print().
אחרי:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = float(request.get_json().get('oldest'))
query = ds_client.query(kind='Visit')
query.add_filter('timestamp', '<', datetime.fromtimestamp(oldest))
query.keys_only()
keys = list(visit.key for visit in query.fetch())
nkeys = len(keys)
if nkeys:
print('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id) for k in keys)))
ds_client.delete_multi(keys)
else:
print('No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
לא חלים שינויים ב-handler הראשי של האפליקציה root().
העברה ל-Python 3
אפליקציית הדוגמה הזו מיועדת להפעלה ב-Python 2 וב-Python 3. השינויים הספציפיים ל-Python 3 מוסברים בחלקים הרלוונטיים של המדריך הזה. לא נדרשים שלבים נוספים או ספריות תאימות.
עדכון של Cloud Tasks
הגרסה האחרונה של ספריית הלקוח של Cloud Tasks שתומכת ב-Python 2 היא 1.5.0. בזמן כתיבת המאמר הזה, הגרסה האחרונה של ספריית הלקוח ל-Python 3 תואמת באופן מלא לגרסה הזו, ולכן לא נדרשים עדכונים נוספים.
עדכון תבנית HTML
גם בקובץ תבנית ה-HTML, templates/index.html, לא נדרשים שינויים. כך מסתיימים כל השינויים הנדרשים כדי להגיע לאפליקציה של מודול 9.
6. סיכום/ניקוי
פריסה ואימות של האפליקציה
אחרי שתסיימו לעדכן את הקוד, בעיקר את ההעברה ל-Python 3, תוכלו לפרוס את האפליקציה באמצעות gcloud app deploy. הפלט צריך להיות זהה לזה של האפליקציות ממודולים 7 ו-8, אלא שהעברתם את הגישה למסד הנתונים לספריית הלקוח של Cloud Datastore ושדרגתם ל-Python 3:

בשלב הזה מסיימים את ה-codelab. מומלץ להשוות את הקוד שלכם למה שמופיע בתיקייה של מודול 9. מעולה!
הסרת המשאבים
כללי
אם סיימתם לעכשיו, מומלץ להשבית את האפליקציה שלכם ב-App Engine כדי להימנע מחיובים. עם זאת, אם רוצים לבצע עוד בדיקות או ניסויים, בפלטפורמת App Engine יש מכסת שימוש בחינם, ולכן כל עוד לא חורגים מרמת השימוש הזו, לא אמורים לחייב אתכם. החישוב הזה מתייחס ל-Compute, אבל יכול להיות שיהיו גם חיובים על שירותים רלוונטיים של App Engine. לכן, כדאי לעיין בדף התמחור שלו כדי לקבל מידע נוסף. אם ההעברה הזו כוללת שירותי ענן אחרים, הם יחויבו בנפרד. בכל מקרה, אם רלוונטי, כדאי לעיין בקטע 'ספציפי ל-codelab הזה' שבהמשך.
חשוב לדעת: פריסה בפלטפורמת מחשוב ללא שרת של Google Cloud, כמו App Engine, כרוכה בעלויות קלות של בנייה ואחסון. ל-Cloud Build יש מכסת שימוש משלו בחינם, כמו גם ל-Cloud Storage. האחסון של התמונה הזו תופס חלק מהמכסה. עם זאת, יכול להיות שאתם גרים באזור שבו אין תוכנית בחינם כזו, ולכן חשוב לעקוב אחרי השימוש בנפח האחסון הנדרש כדי לצמצם את העלויות הפוטנציאליות. התיקיות הספציפיות ב-Cloud Storage שצריך לבדוק כוללות:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- הקישורים לאחסון שלמעלה תלויים ב
PROJECT_IDובמיקום *LOC*ation, לדוגמה,usאם האפליקציה מאוחסנת בארה"ב.
מצד שני, אם אתם לא מתכוונים להמשיך עם האפליקציה הזו או עם Codelabs אחרים שקשורים להעברה, ואתם רוצים למחוק הכול באופן סופי, אתם יכולים להשבית את הפרויקט.
ספציפי ל-Codelab הזה
השירותים שמופיעים בהמשך הם ייחודיים ל-codelab הזה. מידע נוסף זמין במסמכי התיעוד של כל מוצר:
- ל-Cloud Tasks יש תוכנית בחינם. פרטים נוספים מופיעים בדף המחירים.
- שירות App Engine Datastore מסופק על ידי Cloud Datastore (Cloud Firestore במצב Datastore), שגם לו יש רמת שירות בחינם. מידע נוסף זמין במחירון שלו.
השלבים הבאים
כאן מסתיים תהליך ההעברה ממשימות push של תור משימות ב-App Engine אל Cloud Tasks. ההעברה האופציונלית מ-Cloud NDB ל-Cloud Datastore מתוארת גם בנפרד (בלי Task Queue או Cloud Tasks) במודול 3. בנוסף למודול 3, יש מודולים נוספים להעברה שמתמקדים במעבר משירותים קודמים בחבילה של App Engine. כדאי לעיין בהם:
- מודול 2: מעבר מ-App Engine NDB ל-Cloud NDB
- מודול 3: מעבר מ-Cloud NDB ל-Cloud Datastore
- מודולים 12-13: מעבר מ-App Engine Memcache ל-Cloud Memorystore
- מודולים 15-16: מעבר מ-App Engine Blobstore ל-Cloud Storage
- מודולים 18-19: App Engine Task Queue (pull tasks) to Cloud Pub/Sub
App Engine כבר לא הפלטפורמה היחידה ללא שרת ב-Google Cloud. אם יש לכם אפליקציית App Engine קטנה או אפליקציה עם פונקציונליות מוגבלת ואתם רוצים להפוך אותה למיקרו-שירות עצמאי, או אם אתם רוצים לפצל אפליקציה מונוליטית לכמה רכיבים שאפשר לעשות בהם שימוש חוזר, אלה סיבות טובות לשקול מעבר ל-Cloud Functions. אם יצירת קונטיינרים הפכה לחלק מתהליך העבודה של פיתוח האפליקציה, במיוחד אם היא כוללת צינור CI/CD (אינטגרציה רציפה/פריסה או מסירה רציפה), כדאי לשקול מעבר אל Cloud Run. התרחישים האלה מוסברים במודולים הבאים:
- מעבר מ-App Engine ל-Cloud Functions: ראו מודול 11
- מעבר מ-App Engine ל-Cloud Run: אפשר לעיין במודול 4 כדי להעביר את האפליקציה לקונטיינר באמצעות Docker, או במודול 5 כדי לעשות זאת בלי קונטיינרים, בלי ידע ב-Docker או בלי
Dockerfiles
המעבר לפלטפורמה אחרת בלי שרת (serverless) הוא אופציונלי, ומומלץ לבדוק מהן האפשרויות הכי טובות לאפליקציות ולתרחישי השימוש שלכם לפני שמבצעים שינויים.
לא משנה איזה מודול העברה תבחרו, תוכלו לגשת לכל התוכן של Serverless Migration Station (סדנאות קוד, סרטונים, קוד מקור [אם זמין]) במאגר הקוד הפתוח שלו. במאגר README יש גם הנחיות לגבי ההעברות שכדאי לבצע וסדר רלוונטי של מודולי ההעברה.
7. מקורות מידע נוספים
בעיות או משוב לגבי Codelabs
אם נתקלתם בבעיות ב-codelab הזה, כדאי לחפש את הבעיה לפני ששולחים דיווח. קישורים לחיפוש וליצירה של בעיות חדשות:
מקורות מידע על העברת נתונים
בטבלה שלמטה מופיעים קישורים לתיקיות של מאגרים למודול 8 (התחלה) ולמודול 9 (סיום). אפשר גם לגשת אליהם ממאגר המידע של כל ההעברות של Codelabs של App Engine, שאפשר לשכפל או להוריד כקובץ ZIP.
Codelab | Python 2 | Python 3 |
(n/a) | ||
יחידת לימוד 9 | (n/a) |
משאבים באינטרנט
בהמשך מופיעים מקורות מידע באינטרנט שעשויים להיות רלוונטיים למדריך הזה:
App Engine
- מסמכי App Engine
- זמן ריצה של Python 2 App Engine (סביבה סטנדרטית)
- זמן ריצה של Python 3 App Engine (סביבה רגילה)
- ההבדלים בין סביבות זמן הריצה של Python 2 ו-Python 3 App Engine (סביבה סטנדרטית)
- מדריך להעברה מ-Python 2 ל-Python 3 ב-App Engine (סביבה רגילה)
- מידע על התמחור ועל המכסות ב-App Engine
Cloud NDB
Cloud Datastore
- מאמרי עזרה בנושא Google Cloud Datastore
- מאגר Google Cloud Datastore
- מידע על התמחור של Cloud Datastore
Cloud Tasks
מידע אחר על Cloud
- Python ב-Google Cloud Platform
- ספריות לקוח Python של Google Cloud
- רמת השימוש 'תמיד בחינם' ב-Google Cloud
- Google Cloud SDK (כלי לשורת פקודה
gcloud) - כל מסמכי התיעוד של Google Cloud
רישיון
עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.