מעבר מ-Python 2.7 ל-Python 3 runtime העדכני

בדף הזה מוסבר איך לבצע מיגרציה מ-Python runtime מהדור הראשון לדור השני. כדי לשדרג את האפליקציה מהדור השני לגרסה העדכנית הנתמכת של Python, אפשר לעיין במאמר בנושא שדרוג של אפליקציה קיימת.

‫Python 2.7 יצא משימוש. לא תוכלו לפרוס אפליקציות Python 2.7, גם אם הארגון שלכם השתמש בעבר במדיניות ארגונית כדי להפעיל מחדש פריסות של סביבות ריצה מדור קודם. אפליקציות Python 2.7 קיימות ימשיכו לפעול ולקבל תנועה. מומלץ לעבור לגרסה הנתמכת האחרונה של Python.

המעבר ל-Python 3 runtime מאפשר לכם להשתמש בתכונות שפה עדכניות ולבנות אפליקציות ניידות יותר עם קוד אידיומטי. סביבת זמן הריצה של Python 3 משתמשת בגרסה העדכנית ביותר של רכיב התרגום של Python בקוד פתוח, שמסופקת על ידי Python Software Foundation. אפליקציות שנוצרו בסביבת זמן הריצה של Python 3 יכולות להשתמש במערכת האקולוגית העשירה של חבילות ומסגרות של Python באפליקציה, כולל אלה שמשתמשות בקוד C, על ידי הצהרה על תלות בקובץ requirements.txt.

סקירה כללית של תהליך ההעברה של זמן הריצה

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

  1. משדרגים את האפליקציה כדי שתהיה תואמת ל-Python 3.

    יש כמה פתרונות שיעזרו לכם לבצע את השדרוג. לדוגמה, אפשר להשתמש ב-Six,‏ Python-Future או Python-Modernize.

    מידע נוסף על השלב הזה בתהליך העברת נתוני זמן הריצה זמין במאמר העברת קוד Python 2 ל-Python 3 באתר התיעוד של Python Software Foundation.

  2. בוחרים אחת משיטות ההטמעה האלה לכל שירות בחבילה של App Engine שהאפליקציה משתמשת בו:

    1. מעבירים את השירותים מהדור הקודם שכלולים באפליקציית Python 2 לשירותים לא מקובצים, לשירותים של צד שלישי או לחלופות מומלצות אחרות. Google Cloud

    2. להמשיך להשתמש בשירותים מדור קודם בחבילה באפליקציות Python 3. הגישה הזו מאפשרת לכם לעבור לשירותים לא מקובצים בהמשך מחזור ההעברה.

    חשוב לבדוק את האפליקציה אחרי העברת כל שירות.

  3. הכנת קובצי ההגדרות של App Engine לסביבת זמן הריצה של Python 3. יש כמה שינויים חשובים שמשפיעים על הגדרות התצורה ב-app.yaml, כולל:

    • ההנחה היא עכשיו שאפליקציות הן threadsafe. אם האפליקציה שלכם לא בטוחה לשימוש עם שרשורים, צריך להגדיר את max_concurrent_requests ב-app.yaml לערך 1. ההגדרה הזו עלולה לגרום ליצירה של יותר מקרים ממה שצריך לאפליקציה בטוחה לשימוש בריבוי תהליכים, ולהוביל לעלויות מיותרות.
    • הקובץ app.yaml כבר לא מעביר בקשות לסקריפטים שלכם. במקום זאת, אתם צריכים להשתמש במסגרת אינטרנט עם ניתוב בתוך האפליקציה, ולעדכן או להסיר את כל רכיבי ה-handler של script ב-app.yaml. דוגמה לאופן שבו עושים זאת באמצעות Flask framework מופיעה בדוגמת הקוד במדריך להעברת נתונים של App Engine ב-GitHub.

      מידע נוסף על שינוי קובץ התצורה הזה וקובצי תצורה אחרים זמין בקטע קובצי תצורה.

  4. בזמני הריצה מהדור השני, יומני האפליקציות לא מוטמעים יותר בתוך יומני הבקשות. כדי להציג את התצוגה המקוננת של יומני הבקשות והאפליקציות ב-Logs Explorer, צריך לבצע שלבים נוספים. מידע נוסף מופיע במאמר בנושא מעבר ל-Cloud Logging.

  5. בודקים ומפעילים את האפליקציה המשודרגת בסביבת Python 3.

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

דוגמאות להמרת אפליקציות Python 2 ל-Python 3 מופיעות במשאבים הנוספים האלה.

ההבדלים העיקריים בין סביבות זמן הריצה של Python 2 ו-Python 3

רוב השינויים שצריך לבצע במהלך ההעברה בזמן הריצה נובעים מההבדלים הבאים בין זמני הריצה של Python 2 ו-Python 3:

הבדלים בשימוש בזיכרון

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

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

הבדלים בשימוש במעבד

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

הבדלים בכותרות הבקשות

סביבות זמן ריצה מהדור הראשון מאפשרות להעביר לאפליקציה כותרות של בקשות עם קווים תחתונים (לדוגמה, X-Test-Foo_bar). בזמן ריצה מדור שני, Nginx מוצג בארכיטקטורת המארח. כתוצאה מהשינוי הזה, סביבות זמן ריצה מהדור השני מוגדרות להסרה אוטומטית של כותרות עם קווים תחתונים (_). כדי למנוע בעיות באפליקציה, מומלץ להימנע משימוש בקווים תחתונים בכותרות של בקשות באפליקציה.

ההבדלים בין העובדים של Gunicorn

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

בעיות תאימות בין Python 2 ו-Python 3

כש-Python 3 הושקה לראשונה בשנת 2008, נוספו לשפה כמה שינויים שלא תואמים לאחור. חלק מהשינויים האלה דורשים רק עדכונים קלים בקוד, כמו שינוי של הצהרת print לפונקציה print(). שינויים אחרים עשויים לדרוש עדכונים משמעותיים בקוד, כמו עדכון האופן שבו מטפלים בנתונים בינאריים, בטקסט ובמחרוזות.

גם הרבה ספריות פופולריות של קוד פתוח, כולל הספריות הרגילות של Python, השתנו כשעברו מ-Python 2 ל-Python 3.

שירותים בחבילה של App Engine בסביבת זמן הריצה של Python 3

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

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

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

קובצי תצורה

כדי להריץ את האפליקציה בסביבת זמן הריצה של Python 3 בסביבה הרגילה של App Engine, יכול להיות שתצטרכו לשנות חלק מקובצי ההגדרות שבהם נעשה שימוש ב-App Engine:

  • app.yaml. ההתנהגות של חלק מהשדות בקובץ ההגדרות app.yamlעברה שינוי. מסירים את השדות שיצאו משימוש ומעדכנים שדות אחרים כמו שמתואר במדריך להעברת נתונים.

  • requirements.txt. יוצרים את הקובץ הזה כדי להתקין רכיבים תלויים של צד שלישי, כולל חבילות Python שדורשות תוספי C מקוריים. ‫App Engine מתקין באופן אוטומטי את התלות האלה במהלך פריסת האפליקציה בסביבת זמן הריצה של Python 3. בעבר, כדי להתקין תלות בסביבת זמן הריצה של Python 2, היה צריך לפרט את הספריות שהועתקו או את הספריות שצורפו לקובץ הזה, ואז להריץ פקודה של pip install -t lib -r requirements.txt.

  • appengine_config.py. הקובץ הזה לא נמצא בשימוש בסביבת זמן הריצה של Python 3, והמערכת מתעלמת ממנו אם הוא נפרס. בעבר, בסביבת זמן הריצה של Python 2, הקובץ הזה שימש להגדרת מודולי Python ולהפניית האפליקציה לספריות של צד שלישי שהועתקו או נארזו בעצמן.

נדרשת מסגרת אינטרנט כדי להפנות בקשות לתוכן דינמי

בזמן הריצה של Python 2, אפשר ליצור מטפלים בכתובות URL בקובץ app.yaml כדי לציין איזו אפליקציה להפעיל כשמתקבלת בקשה לכתובת URL ספציפית או לתבנית כתובת URL ספציפית.

בזמן הריצה של Python 3, האפליקציה צריכה להשתמש ב-framework לאינטרנט כמו Flask או Django כדי להפנות בקשות לתוכן דינמי, במקום להשתמש ב-handlers של כתובות URL ב-app.yaml. לגבי תוכן סטטי, אפשר להמשיך ליצור רכיבי handler של כתובות URL בקובץ app.yaml של האפליקציה.

אפליקציות עם תוכן סטטי בלבד

כשמארחים אפליקציית אינטרנט סטטית ב-App Engine, מציינים מטפלים בקובץ app.yaml כדי למפות כתובות URL לקבצים סטטיים.

ב-Python 2, אם בקשה לא תואמת לאף אחד מהמטפלים שצוינו בקובץ app.yaml, ‏ App Engine מחזיר קוד שגיאה 404.

ב-Python 3, אם בקשה לא תואמת לאף אחד מהמטפלים, App Engine מחפש קובץ main.py ומחזיר שגיאת 5xx אם לא נמצא קובץ main.py. מכיוון שאפליקציות App Engine עם תוכן סטטי בלבד לא דורשות קובץ main.py, רוב המשתמשים רואים את השגיאה הזו, בנוסף לשגיאות בהפעלת מופעים ביומני האפליקציה.

כדי לשמור על אותה התנהגות של החזרת שגיאה 404 כשאין התאמה לאף אחד מהמטפלים הסטטיים, וכדי להימנע משגיאות ביומנים, אפשר:

  • מוסיפים handler סטטי catch-all שמפנה לספרייה ריקה בקובץ app.yaml
  • מוסיפים אפליקציה דינמית פשוטה בקובץ main.py כדי להחזיר שגיאה 404

דוגמאות לשימוש בכל אחת מהאפשרויות:

app.yaml

יוצרים ספרייה ריקה בספריית השורש של האפליקציה, כמו empty/. בקטע handler בקובץ app.yaml, יוצרים handler חדש בסוף הקובץ כדי לטפל בכל דפוסי כתובות ה-URL האחרים, ומציינים את הספרייה empty ברכיבים static_files ו-upload:

  handlers:
  - url:
    .
    .
    .
  - url: /(.*)$
    static_files: empty/\1
    upload: empty/.*$

main.py

יוצרים קובץ main.py ומוסיפים את הקוד הבא כדי להחזיר שגיאת 404:

  def app(env, start_response):
    start_response('404 Not Found', [('Content-Type','text/html')])
    return [b"Not Found"]

בדיקה

מומלץ להשתמש בגישת בדיקה שמתאימה ל-Python ולא להסתמך על dev_appserver. לדוגמה, אפשר להשתמש ב-venv כדי ליצור סביבה מקומית מבודדת של Python 3. אפשר להשתמש בכל מסגרת בדיקה רגילה של Python כדי לכתוב את הבדיקות של היחידות, השילובים והמערכת. אפשר גם להגדיר גרסאות פיתוח של השירותים או להשתמש באמולטורים מקומיים שזמינים למוצרים רבים של Google Cloud.

אפשר גם להשתמש בגרסת התצוגה המקדימה של dev_appserver שתומכת ב-Python 3. מידע נוסף על תכונת הבדיקה הזו זמין במאמר שימוש בשרת פיתוח מקומי.

פריסה

אין תמיכה בפריסות דרך appcfg.py ל-Python 3. במקום זאת, משתמשים בgcloud שורת הפקודה כדי לפרוס את האפליקציה.

רישום ביומן

הרישום בזמן הריצה של Python 3 מתבצע לפי תקן הרישום ב-Cloud Logging. בזמן הריצה של Python 3, יומני האפליקציות כבר לא מקובצים עם יומני הבקשות, אלא מופרדים לרשומות שונות. מידע נוסף על קריאה וכתיבה של יומנים בסביבת זמן הריצה של Python 3 זמין במדריך לרישום ביומן.

מקורות מידע נוספים על העברת נתונים

למידע נוסף על העברת אפליקציות App Engine לשירותי Cloud עצמאיים או לסביבת זמן הריצה של Python 3, אפשר לעיין במקורות המידע הבאים של App Engine: