מעבר ממשימות הדחיפה לתור המשימות של App Engine ל-Cloud Tasks (מודול 8)

1. סקירה כללית

סדרת הServerless Migration Station של Codelabs (מדריכים מעשיים בקצב עצמי) וסרטונים קשורים נועדו לעזור להעביר מפתחים ללא שרת (serverless) של Google Cloud, באמצעות העברת אפליקציות מדור קודם באמצעות שירותי Google Cloud. כך האפליקציות שלכם יהיו יותר ניידות ויהיו לכם יותר אפשרויות וגמישות, כך שתוכלו להשתלב עם מגוון רחב יותר של מוצרי Cloud ולגשת אליהם בקלות, ולהשדרג בקלות רבה יותר לגרסאות חדשות יותר של שפות. הסדרה מתמקדת בהתחלה במשתמשי Cloud הראשונים, ובעיקר מפתחי App Engine (בסביבה סטנדרטית), אבל היא רחבה מספיק כדי לכלול פלטפורמות אחרות ללא שרת (serverless), כמו Cloud Functions ו-Cloud Run, או במקומות אחרים, אם רלוונטי.

המטרה של ה-codelab הזו היא להראות למפתחי App Engine ב-Python 2 איך לעבור מתור המשימות של App Engine (משימות בדחיפה) ל-Cloud Tasks. יש גם העברה משתמעת מ-App Engine NDB ל-Cloud NDB כדי לקבל גישה ל-Datastore (אז היא מתוארת בעיקר במודול 2).

הוספנו את השימוש במשימות push במודול 7, והעברנו את השימוש הזה ל-Cloud Tasks במודול 8, ואז המשכנו ל-Python 3 ול-Cloud Datastore במודול 9. משתמשים שמשתמשים בתכונה 'תורי משימות' למשימות משיכה יועברו ל-Cloud Pub/Sub ויפנו למודולים 18-19 במקום זאת.

כאן אפשר להבין איך

למה תזדקק?

סקר

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לדעתך לחוויה שלך עם Python?

מתחילים בינונית בקיאים

איזה דירוג מגיע לדעתך לחוויית השימוש שלך בשירותי Google Cloud?

מתחילים בינונית בקיאים

2. רקע

תור המשימות של App Engine תומך גם במשימות דחיפה וגם במשימות משיכה. כדי לשפר את ניידות האפליקציות, צוות Google Cloud ממליץ לעבור משירותים בחבילה מדור קודם כמו 'תור המשימות', לשירותים עצמאיים אחרים ב-Cloud או לשירותים מקבילים של צד שלישי.

העברה של משימות משיכה נכללת במודולים של העברה 18-19, ואילו מודולים 7-9 מתמקדים בהעברה של משימות דחיפה. כדי לעבור ממשימות הדחיפה לתור המשימות של App Engine, הוספנו את השימוש שלו לאפליקציה לדוגמה הקיימת של App Engine ב-Python 2, רושמת ביקורים חדשים בדפים ומציגה את הביקורים האחרונים. ה-Codelab של מודול 7 מוסיף משימת דחיפה למחיקת הביקורים הישנים ביותר — הם אף פעם לא יוצגו שוב, אז למה הם צריכים לתפוס נפח אחסון נוסף ב-Datastore? ה-Codelab של מודול 8 הזה שומר את אותה הפונקציונליות, אבל הוא מעביר את מנגנון התורן הבסיסי ממשימות הדחיפה לתור המשימות אל Cloud Tasks. כמו כן, הוא חוזר על ההעברה של מודול 2 מ-App Engine NDB ל-Cloud NDB בשביל גישה ל-Datastore.

המדריך הזה כולל את השלבים הבאים:

  1. הגדרה/עבודה מוקדמת
  2. עדכון ההגדרות האישיות
  3. שינוי קוד האפליקציה

3. הגדרה/עבודה מוקדמת

בקטע הזה נסביר איך:

  1. הגדרת פרויקט ב-Cloud
  2. אחזור של אפליקציה בסיסית לדוגמה
  3. (מחדש) פריסה ואימות של אפליקציה בסיסית
  4. הפעלת שירותים/ממשקי API חדשים של Google Cloud

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

1. הגדרת הפרויקט

אם השלמתם את Module 7 Codelab, צריך להשתמש שוב באותו פרויקט (ובקוד). לחלופין, אפשר ליצור פרויקט חדש לגמרי או להשתמש שוב בפרויקט קיים אחר. צריך לוודא שלפרויקט יש חשבון פעיל לחיוב ואפליקציית App Engine מופעלת. אתם יכולים למצוא את מזהה הפרויקט שלכם למקרה הצורך במהלך ה-Codelab הזה, ולהשתמש בו בכל פעם שאתם נתקלים במשתנה PROJECT_ID.

2. אחזור של אפליקציה בסיסית לדוגמה

אחת מהדרישות המוקדמות היא אפליקציית App Engine פעילה של Module 7: משלימים את Module 7 Codelab (מומלץ) או מעתיקים את אפליקציית Module 7 מהמאגר. בין אם אתם משתמשים בקוד של מודול 7 שלכם או שלנו, הקוד של מודול 7 הוא המקום שבו נתחיל ("התחלה"). ה-Codelab הזה ינחה אותך לאורך ההעברה, ויסתיים בקוד שדומה למה שמופיע בתיקיית המאגר של מודול 8 (FINISH).

התיקייה צריכה להיראות כמו בדוגמה הבאה, אולי עם התיקייה lib, בלי קשר לאפליקציית Module 7 שבה אתם משתמשים:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

3. (מחדש) פריסה ואימות של אפליקציה בסיסית

מבצעים את השלבים הבאים כדי לפרוס את אפליקציית מודול 7:

  1. אם קיימת תיקייה כזו, מוחקים את התיקייה lib ומריצים את הפקודה pip install -t lib -r requirements.txt כדי לאכלס מחדש את lib. יכול להיות שתצטרכו להשתמש ב-pip2 במקום זאת, אם במחשב הפיתוח שלכם מותקנות גם Python 2 וגם גרסה 3.
  2. חשוב לוודא שהתקנתם ואתחלתם את כלי שורת הפקודה gcloud, ושבדקתם את השימוש בו.
  3. (אופציונלי) אם לא רוצים להזין את ה-PROJECT_ID עם כל פקודת gcloud שיוצרים, מגדירים את הפרויקט ב-Cloud לערך gcloud config set project PROJECT_ID.
  4. פריסת האפליקציה לדוגמה באמצעות gcloud app deploy
  5. מוודאים שהאפליקציה פועלת כמצופה ללא בעיות. אם השלמתם את ה-Codelab במודול 7, האפליקציה מציגה את המבקרים המובילים יחד עם הביקורים האחרונים (איור בהמשך). למטה אפשר לראות אילו משימות ישנות יותר יימחקו.

4aa8a2cb5f527079.png

4. הפעלת שירותים/ממשקי API חדשים של Google Cloud

באפליקציה הישנה נעשה שימוש בשירותים בחבילה של App Engine שלא מחייבים הגדרות נוספות, אבל שירותי Cloud עצמאיים כן. בנוסף, האפליקציה המעודכנת תשתמש גם ב-Cloud Tasks וגם ב-Cloud Datastore (דרך ספריית הלקוח של Cloud NDB). לחלק ממוצרי Cloud יש את האפשרות "חינם תמיד" מכסות ברמה, כולל App Engine, Cloud Datastore ו-Cloud Tasks. כל עוד לא תחרגו מהמגבלות האלה, לא תצברו חיובים על השלמת המדריך הזה. את ממשקי Cloud API אפשר להפעיל מ-Cloud Console או משורת הפקודה, בהתאם להעדפות שלכם.

ממסוף Cloud

נכנסים לדף הספרייה של API Manager (לפרויקט הנכון) במסוף Cloud, ומחפשים את ממשקי Cloud Datastore ואת Cloud Tasks APIs באמצעות סרגל החיפוש שבמרכז הדף:

c7a740304e9d35b.png

לוחצים על הלחצן הפעלה לכל API בנפרד — ייתכן שתתבקשו להזין נתוני חיוב. זוהי דוגמה להצגת הדף של ספריית Cloud Pub/Sub API (אין להפעיל את Pub/Sub API עבור הקוד הזה, אלא רק את Cloud Tasks ו-Datastore):

1b6c0a2a73124f6b.jpeg

משורת הפקודה

הפעלת ממשקי API מהמסוף היא אינפורמטיבית מבחינה ויזואלית, אבל יש משתמשים שמעדיפים את שורת הפקודה. שולחים את הפקודה gcloud services enable cloudtasks.googleapis.com datastore.googleapis.com כדי להפעיל את שני ממשקי ה-API בו-זמנית:

$ gcloud services enable cloudtasks.googleapis.com datastore.googleapis.com
Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

ייתכן שתתבקשו להזין נתוני חיוב. אם ברצונך להפעיל ממשקי Cloud API אחרים וברצונך לדעת מהם מזהי ה-URI שלהם הם נמצאים בחלק התחתון של הדף 'ספרייה' של כל API. לדוגמה, צריך להזין את pubsub.googleapis.com בתור 'שם השירות' בתחתית דף Pub/Sub שלמעלה.

אחרי ביצוע השלבים, לפרויקט שלכם תהיה גישה לממשקי ה-API. בשלב הזה צריך לעדכן את האפליקציה כך שתשתמש בממשקי ה-API האלה.

4. עדכון ההגדרות האישיות

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

requirements.txt

מודול 8 מחליף את השימוש ב-App Engine NDB ובתור משימות ממודול 1 עם Cloud NDB ו-Cloud Tasks. צריך להוסיף את google-cloud-ndb ואת google-cloud-tasks לישות requirements.txt כדי להצטרף ל-flask ממודול 7:

flask
google-cloud-ndb
google-cloud-tasks

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

app.yaml

כשמשתמשים בספריות לקוח של Cloud, לזמן הריצה של Python 2 App Engine נדרשות חבילות ספציפיות של צד שלישי, כלומר grpcio ו-setuptools. משתמשי Python 2 חייבים להציג ספריות מובנות כמו אלה, יחד עם הגרסה זמינה או הגרסה האחרונה ב-app.yaml. אם עדיין אין לך קטע ב-libraries, צריך ליצור אותו ולהוסיף את שתי הספריות באופן הבא:

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest

כשמעבירים את האפליקציה שלך, ייתכן שכבר יש בה קטע בשם libraries. אם כן, וחסרים grpcio ו-setuptools, פשוט צריך להוסיף אותם לקטע libraries הקיים. עכשיו, ה-app.yaml המעודכן אמור להיראות כך:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest

appengine_config.py

הקריאה google.appengine.ext.vendor.add() ב-appengine_config.py מחברת לאפליקציה שלך ספריות של צד שלישי שהעתקת (שנקראות לפעמים 'ספק' או 'קיבוץ עצמי') של צד שלישי ב-lib. למעלה ב-app.yaml, הוספנו ספריות מובנות של צד שלישי, והן צריכות setuptools.pkg_resources.working_set.add_entry() כדי לקשר את האפליקציה שלך לחבילות המובנות ב-lib. בהמשך מופיעים מודול 1 המקורי appengine_config.py ואחרי שמעדכנים את מודול 8:

לפני:

from google.appengine.ext import vendor

# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)

אחרי:

import pkg_resources
from google.appengine.ext import vendor

# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)

תיאור דומה מופיע גם במסמכי התיעוד בנושא העברה של App Engine.

5. שינוי קוד האפליקציה

הקטע הזה כולל עדכונים לקובץ הראשי של האפליקציה, main.py, שמחליף את השימוש בתורי המשימות של App Engine בתור Cloud Tasks. אין שינויים בתבנית האינטרנט, templates/index.html – שתי האפליקציות צריכות לפעול באופן זהה ולהציג את אותם הנתונים. השינויים באפליקציה הראשית מתחלקים לארבע פעולות לביצוע:

  1. ייבוא ואתחול של עדכונים
  2. עדכון הפונקציונליות של מודל הנתונים (Cloud NDB)
  3. מעבר ל-Cloud Tasks (ול-Cloud NDB)
  4. עדכון handler (התראות) במשימה

1. ייבוא ואתחול של עדכונים

  1. מחליפים את App Engine NDB (google.appengine.ext.ndb) ואת 'הבאים בתור' (google.appengine.api.taskqueue) ב-Cloud NDB (google.cloud.ndb) וב-Cloud Tasks (google.cloud.tasks), בהתאמה.
  2. ספריות לקוח של Cloud מחייבות אתחול ויצירה של 'לקוחות API'. להקצות אותם ל-ds_client ול-ts_client, בהתאמה.
  3. במסמכי התיעוד בנושא 'תור משימות' כתוב: "App Engine מספק תור ברירת מחדל לדחיפה, בשם default, והוא מוגדר ומוכן לשימוש עם הגדרות ברירת המחדל". שירות Cloud Tasks לא מספק תור default (מכיוון שהוא מוצר Cloud עצמאי שלא תלוי ב-App Engine), ולכן נדרש קוד חדש כדי ליצור תור ב-Cloud Tasks בשם default.
  4. תור המשימות של App Engine לא מחייב לציין אזור מפני שהוא משתמש באזור שבו האפליקציה פועלת. עם זאת, מכיוון ש-Cloud Tasks הוא עכשיו מוצר עצמאי, נדרש אזור, והאזור הזה צריך להיות תואם לאזור שבו האפליקציה פועלת. כדי ליצור 'שם נתיב שעומד בדרישות', צריך להזין את שם האזור ומזהה הפרויקט ב-Cloud בתור המזהה הייחודי של התור.

העדכונים שמתוארים בנקודה השלישית והרביעית שלמעלה מרכיבים את רוב הקבועים הנוספים ואת האתחול הנדרשים. לצפייה בקטע "לפני" וגם אחרי למטה ולבצע את השינויים האלה בחלק העליון של main.py.

לפני:

from datetime import datetime
import logging
import time
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb

app = Flask(__name__)

אחרי:

from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
from google.cloud import ndb, tasks

app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()

_, 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)

2. עדכון הפונקציונליות של מודל הנתונים (Cloud NDB)

App Engine NDB ו-Cloud NDB פועלים באופן כמעט זהה. אין שינויים משמעותיים במודל הנתונים או בפונקציה store_visit(). ההבדל הבולט היחיד הוא שיצירת הישות Visit ב-store_visit() נכללת עכשיו בבלוק with של Python. כדי להשתמש ב-Cloud NDB צריך לשלוט בכל הגישה ל-Datastore דרך מנהל ההקשר שלו, ולכן ההצהרה with. קטעי הקוד הבאים ממחישים את ההבדל הקטן הזה במעבר ל-Cloud NDB. יישום השינוי

לפני:

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'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

אחרי:

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()

3. מעבר ל-Cloud Tasks (ול-Cloud NDB)

השינוי הקריטי ביותר בהעברה הזו יחליף את התשתית של הוספה לתור. הפעולה הזו מתבצעת בפונקציה fetch_visits(), שבה נוצרת משימה (push) למחיקת ביקורים ישנים, וממשיכה להיכנס לתור לביצוע. עם זאת, הפונקציונליות המקורית ממודול 7 תישאר ללא שינוי:

  1. שאילתה לביקורים האחרונים ביותר.
  2. במקום להחזיר את הביקורים האלה באופן מיידי, אפשר לשמור את חותמת הזמן של ה-Visit האחרון, שהוא הישן ביותר שמוצג. אפשר למחוק בבטחה את כל הביקורים שהתרחשו לפני כן.
  3. מציגים את חותמת הזמן כמחרוזת צפה (float) ומחרוזת באמצעות כלי עזר סטנדרטיות של Python, ומשתמשים בקיבולת שונה, כמו הצגה למשתמש, הוספה ליומנים, העברה ל-handler וכו'.
  4. אפשר ליצור משימת דחיפה עם חותמת הזמן הזו כמטען הייעודי (payload) שלה יחד עם /trim ככתובת ה-URL.
  5. ה-handler של המשימה נקרא בסופו של דבר דרך POST HTTP לכתובת ה-URL הזו.

תהליך העבודה הזה מאויר באמצעות הקטע 'לפני'. קטע קוד:

לפני:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    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)
    taskqueue.add(url='/trim', params={'oldest': oldest})
    return data, oldest_str

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

  1. גלישה של שאילתת Visit בתוך בלוק with של Python (העברה של מודול 2 אל Cloud NDB)
  2. יצירת מטא-נתונים של Cloud Tasks, כולל מאפיינים צפויים כמו מטען ייעודי (payload) של חותמת זמן וכתובת URL, אבל גם הוספת סוג MIME וקידוד JSON של המטען הייעודי (payload).
  3. משתמשים בלקוח Cloud Tasks API כדי ליצור את המשימה עם המטא-נתונים ושם הנתיב המלא של התור.

השינויים האלה ב-fetch_visits() מודגמים למטה:

אחרי:

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 data, oldest_str

4. עדכון handler (התראות) במשימה

הפונקציה (push) של ה-handler לא מצריכה עדכונים משמעותיים. נדרשת רק הפעלה. המצב הזה רלוונטי ל'תור המשימות' או ל-Cloud Tasks. "הקוד הוא הקוד," אז הם אומרים. עם זאת, יש כמה שינויים קלים:

  1. המטען הייעודי של חותמת הזמן הועבר מילה במילה אל 'תור המשימות', אבל הוא היה מקודד ב-JSON עבור Cloud Tasks ולכן צריך לנתח אותו ב-JSON עם ההגעה.
  2. בקריאה מסוג POST ל-HTTP שנשלחת אל /trim עם 'תור המשימות' היה MIMEtype מרומז של application/x-www-form-urlencoded, אבל ב-Cloud Tasks, הוא מוגדר במפורש כ-application/json, כך שיש דרך קצת שונה לחילוץ המטען הייעודי (payload).
  3. שימוש במנהל ההקשר של הלקוח ב-Cloud NDB API (העברת מודול 2 ל-Cloud NDB).

בהמשך מפורטים קטעי הקוד לפני ואחרי ביצוע השינויים ב-handler של המשימה, trim():

לפני:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = request.form.get('oldest', type=float)
    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

אחרי:

@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

אין עדכונים ל-handler הראשי של האפליקציה root() או לתבנית האינטרנט templates/index.html.

6. סיכום/ניקוי

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

פריסה ואימות של אפליקציה

פורסים את האפליקציה באמצעות gcloud app deploy. הפלט אמור להיות זהה לאפליקציית Module 7, אבל חשוב לזכור שהחלפתם את המוצר בתור 'הבאים בתור', ולכן האפליקציה שלכם ניידת יותר מבעבר.

4aa8a2cb5f527079.png

הסרת המשאבים

כללי

אם סיימתם בינתיים, מומלץ להשבית את אפליקציית App Engine כדי להימנע מצבירת חיובים. עם זאת, אם אתם רוצים להתנסות בפיצ'רים נוספים או להתנסות בהם, בפלטפורמת App Engine יש מכסה בחינם, וכל עוד אתם לא חורגים ממכסת השימוש הזו, לא נחייב אתכם. הבקשה נועדה למחשוב, אבל ייתכן שיחולו חיובים גם על שירותים רלוונטיים של App Engine. למידע נוסף, יש לעיין בדף התמחור של האפליקציה. אם ההעברה הזו כוללת שירותי ענן אחרים, הם מחויבים בנפרד. בכל מקרה, אם רלוונטי, ראו "ספציפי ל-Codelab זה" שבהמשך.

גילוי נאות מלא, פריסה בפלטפורמת מחשוב ללא שרת (serverless) של Google Cloud, כמו App Engine, כרוכה בעלויות נמוכות של build ואחסון. ל-Cloud Build יש מכסה משלה בחינם, כמו גם ל-Cloud Storage. נפח האחסון של התמונה הזו תופס חלק מהמכסה. עם זאת, ייתכן שאתם גרים באזור שאין בו תוכנית ללא תשלום כזה, לכן כדאי שתהיו מודעים לשימוש שלכם בנפח האחסון כדי למזער את העלויות הפוטנציאליות. 'תיקיות' ספציפיות של Cloud Storage כדאי לבדוק:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • הקישורים לנפח האחסון שלמעלה תלויים במאפיין PROJECT_ID ובמאפיין *LOC*שלך, לדוגמה, "us" אם האפליקציה מתארחת בארה"ב.

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

ספציפי ל-Codelab הזה

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

השלבים הבאים

סיימנו את ההעברה שלנו ממשימות הדחיפה לתור המשימות של App Engine אל Cloud Tasks. אם ברצונך להמשיך לנייד את האפליקציה הזו ל-Python 3 ולעבור עוד יותר ל-Cloud Datastore מ-Cloud NDB, כדאי לשקול את מודול 9.

Cloud NDB קיים במיוחד למפתחי אפליקציות של Python 2 App Engine, ומספק חוויית משתמש כמעט זהה, אבל ל-Cloud Datastore יש ספריית לקוח מקורית שמיועדת למשתמשים שלא משתמשים ב-App Engine או למשתמשים חדשים (Python 3). עם זאת, מכיוון ש-Cloud NDB זמין בשביל Python 2 וגם 3, לא נדרשת העברה ל-Cloud Datastore.

גם Cloud NDB וגם Cloud Datastore ניגשים ל-Datastore (אבל בדרכים שונות), ולכן כדאי לעבור ל-Cloud Datastore רק אם כבר יש לכם אפליקציות אחרות, בעיקר אפליקציות שאינן של App Engine, שמשתמשות ב-Cloud Datastore ורצון ליצור סטנדרטיזציה בספריית לקוח יחידה של Datastore. ההעברה האופציונלית הזו מ-Cloud NDB ל-Cloud Datastore גם עוסקת בנפרד (בלי 'תור משימות' או Cloud Tasks) במודול 3.

מעבר למודולים 3, 8 ו-9, מודולים אחרים של העברה שמתמקדים בהפסקת השימוש בשירותים בחבילה מהדור הקודם של App Engine, כולל:

App Engine היא כבר לא הפלטפורמה היחידה ללא שרת (serverless) ב-Google Cloud. אם יש לכם אפליקציה קטנה של App Engine או אפליקציה שיש לה פונקציונליות מוגבלת ואתם רוצים להפוך אותה למיקרו-שירות (microservice) עצמאי, או שאתם רוצים לפצל אפליקציה מונוליתית למספר רכיבים לשימוש חוזר, כדאי לשקול לעבור ל-Cloud Functions. אם יצירת קונטיינרים הפכה לחלק מתהליך פיתוח האפליקציות שלכם, במיוחד אם היא מורכבת מצינור עיבוד נתונים של CI/CD (אינטגרציה רציפה (CI/CD)/פיתוח רציף (continuous delivery) או פריסה), מומלץ לעבור ל-Cloud Run. התרחישים האלה מתוארים במודולים הבאים:

  • מעבר מ-App Engine ל-Cloud Functions: ראו מודול 11
  • מעבר מ-App Engine ל-Cloud Run: אפשר לעיין במודול 4 ליצירת קונטיינרים לאפליקציה באמצעות Docker, או במודול 5 כדי לבצע אותו ללא קונטיינרים, ידע ב-Docker או Dockerfile

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

בלי קשר למודול ההעברה הרצוי, כל התוכן של תחנת המיגרציה ללא שרת (serverless) (codelabs, סרטונים, קוד מקור [אם הוא זמין]) יהיה זמין במאגר הקוד הפתוח שלו. README של המאגר גם מספק הדרכה לגבי ההעברות שכדאי לשקול ו"הזמנה" רלוונטית של מודולי העברה.

7. מקורות מידע נוספים

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

בעיות/משוב על Codelabs

אם נתקלתם בבעיות ב-Codelab הזה, צריך קודם לחפש את הבעיה לפני השליחה. קישורים לחיפוש וליצירת בעיות חדשות:

משאבים להעברה

בטבלה שלמטה מופיעים הקישורים לתיקיות המאגר של מודול 7 (START) ומודול 8 (FINISH).

Codelab

ֶPython 2

ֶPython 3

יחידת לימוד 7

קוד

code (לא מוצג במדריך הזה)

יחידת לימוד 8 (Codelab זה)

קוד

(לא רלוונטי)

מקורות מידע אונליין

בהמשך מופיעים מקורות מידע מקוונים שעשויים להיות רלוונטיים למדריך זה:

תור המשימות של App Engine ו-Cloud Tasks

App Engine NDB ו-Cloud NDB (Datastore)

פלטפורמת App Engine

מידע אחר בענן

סרטונים

רישיון

היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.