בדף הזה מוסבר איך להעביר נתונים מהדור הראשון לדור השני של סביבות זמן ריצה של Java. כדי לשדרג אפליקציה מהדור השני לגרסה העדכנית ביותר של Java שנתמכת, אפשר לעיין במאמר שדרוג של אפליקציה קיימת.
Java 8 יצאה משימוש. לא תוכלו לפרוס אפליקציות של Java 8, גם אם הארגון שלכם השתמש בעבר במדיניות ארגונית כדי להפעיל מחדש פריסות של סביבות ריצה מדור קודם. האפליקציות הקיימות של Java 8 ימשיכו לפעול ולקבל תנועה. אנחנו ממליצים לעבור לגרסה נתמכת עדכנית של Java.
מעבר לזמני ריצה של Java מהדור השני מאפשר לכם להשתמש בתכונות שפה עדכניות ולבנות אפליקציות ניידות יותר עם קוד אידיומטי.
הסבר על אפשרויות ההעברה
כדי לצמצם את המאמץ והמורכבות של ההעברה בזמן הריצה, הסביבה הרגילה של App Engine מאפשרת לכם לגשת להרבה שירותים ולממשקי API מדור קודם, כמו Memcache, בזמני הריצה של Java מהדור השני. אפליקציית Java יכולה לקרוא לממשקי ה-API של השירותים הכלולים דרך קובץ ה-JAR של App Engine API, ולקבל גישה לרוב היכולות כמו בסביבת זמן הריצה של Java 8.
יש לכם גם אפשרות להשתמש ב Google Cloud מוצרים שמציעים פונקציונליות דומה לזו של חבילות השירותים הקודמות. המוצרים האלה מספקים ספריות לקוח של Java ב-Cloud. Google Cloud לגבי חבילות השירותים שלא זמינות כמוצרים נפרדים ב-Google Cloud, כמו עיבוד תמונות, חיפוש והודעות, אפשר להשתמש בספקים של צד שלישי או בפתרונות עקיפים אחרים.
מידע נוסף על מעבר לשירותים לא מקובצים זמין במאמר מעבר משירותים מקובצים.
יש כמה הבדלים באופן שבו מבצעים את ההעברה בזמן הריצה, בהתאם לבחירה אם להשתמש בשירותים הקודמים בחבילה:
| מעבר לזמני ריצה של Java מדור שני עם שירותים בחבילה | מעבר לזמני ריצה של Java מדור שני בלי שירותים בחבילה |
|---|---|
| גישה לשירותים בחבילה באמצעות קובץ ה-JAR של ממשקי ה-API של App Engine. | אפשר גם להשתמש ב Google Cloud מוצרים מומלצים או בשירותים של צד שלישי. |
|
משתמשים ב-
יכול להיות שתצטרכו גם להגדיר קובצי YAML נוספים, בהתאם לתכונות שבהן האפליקציה משתמשת. |
משתמשים ב-
יכול להיות שתצטרכו גם להגדיר קובצי YAML נוספים, בהתאם לתכונות שבהן האפליקציה משתמשת. |
| הפריסה של האפליקציות מתבצעת באמצעות Jetty. משתמשים בפורמט WAR כדי לארוז את האפליקציה. | הפריסה של האפליקציות מתבצעת באמצעות השרת שלכם. משתמשים בפורמט JAR כדי לארוז את האפליקציה. כדי לקבל מידע נוסף על המרת קובץ WAR קיים לקובץ JAR שניתן להפעלה, אפשר לעיין במאמר אריזה מחדש של קובץ WAR. |
סקירה כללית של תהליך המיגרציה
בהמשך מפורטים כמה שינויים שאולי תצטרכו לבצע באפליקציית Java 8 הקיימת שלכם ב-App Engine ובתהליך הפריסה כדי להשתמש בסביבות זמן הריצה של Java מהדור השני:
- הורדה של Google Cloud CLI
- להעביר את התוסף העצמאי של App Engine Maven אל התוסף של Maven שמבוסס על CLI של gcloud או אל התוסף של Gradle שמבוסס על CLI של gcloud.
- אם אתם משתמשים בשירותים הקודמים בחבילה, צריך להתקין את App Engine API JAR.
ההבדלים העיקריים בין Java 8 לבין סביבות זמן הריצה של Java מהדור השני
בהמשך מופיע סיכום של ההבדלים בין Java 8 לבין סביבות זמן הריצה של Java מהדור השני בסביבת App Engine סטנדרטית:
| זמן ריצה של Java 8 | סביבות זמן ריצה של Java מהדור השני | |
|---|---|---|
| פריסת השרת | השרת נפרס בשבילכם באמצעות Jetty | אם האפליקציה שלכם לא משתמשת בשירותים הקודמים שצורפו לחבילה, תצטרכו לפרוס שרת בעצמכם.1 |
| שירותים בחבילה מדור קודם של App Engine | מסופק | מסופק |
| אפשרות להשתמש בספריות לקוח של Cloud ל-Java | כן | כן |
| תמיכה בתוסף שפה ובספריית המערכת | כן | כן |
| גישה לרשת חיצונית | כן | כן |
| גישה למערכת הקבצים | גישת קריאה/כתיבה אל /tmp
|
גישת קריאה/כתיבה אל /tmp
|
| שפת זמן הריצה | הותאם ל-App Engine | זמן ריצה ללא שינויים, קוד פתוח |
| מנגנון בידוד | ארגז חול לקונטיינרים מבוסס gVisor | ארגז חול לקונטיינרים מבוסס gVisor |
| בדיקה באמצעות שרת פיתוח מקומי | נתמך | נתמך |
| הגדרת thread safety | אפשר לציין את הגרסה בקובץ appengine-web.xml.
|
אי אפשר לציין את הערך הזה בקובצי התצורה. ההנחה היא שכל האפליקציות בטוחות לשימוש עם שרשורים.3 |
| רישום ביומן | משתמשים ב-java.util.logging.ConsoleHandler, שכותב ל-stderr ומרוקן את הזרם אחרי כל רשומה. |
Standard Cloud Logging 2 |
| תמיכה בתוסף DataNucleus בגרסה 2.x | נתמך | לא נתמך 4 |
הערות:
אם האפליקציה שלכם לא משתמשת בשירותים המצורפים מדור קודם, סביבות זמן הריצה של Java מהדור השני יכולות להריץ כל מסגרת Java, כל עוד אתם אורזים שרת אינטרנט שמוגדר להגיב לבקשות HTTP ביציאה שצוינה במשתנה הסביבה
PORT(מומלץ) או ביציאה 8080. לדוגמה, סביבות זמן הריצה של Java מהדור השני יכולות להריץ קובץ JAR של Spring Boot Uber כמו שהוא. דוגמאות נוספות מופיעות בקטע גמישות המסגרת.אם האפליקציה שלכם משתמשת בשירותים הקודמים שצורפו, App Engine פורס אותה באמצעות Jetty באותו אופן כמו בסביבת זמן הריצה של Java 8.
הרישום ביומן בזמני הריצה של Java מדור שני מתבצע לפי תקן הרישום ביומן ב-Cloud Logging. בזמני הריצה של Java מהדור השני, יומני האפליקציות כבר לא מצורפים ליומני הבקשות, אלא מופרדים ברשומות שונות. מידע נוסף על קריאה וכתיבה של יומנים בסביבות זמן הריצה של Java מהדור השני זמין במדריך לרישום ביומן.
כדי להגדיר אפליקציה לא בטוחה לשימוש עם שרשורים בסביבת זמן ריצה של Java מהדור השני, בדומה להגדרה של
<threadsafe>false</threadsafe>ב-Java 8, צריך להגדיר את הערך של max concurrency ל-1 בקובץapp.yamlאו בקובץappengine-web.xmlאם משתמשים בשירותים מדור קודם.Google לא תומכת בספריית DataNucleus בסביבות זמן ריצה מהדור השני. גרסאות חדשות יותר של DataNucleus לא תואמות לאחור לגרסאות שנעשה בהן שימוש ב-Java 8. כדי לגשת ל-Datastore, מומלץ להשתמש בספריית לקוח במצב Datastore או בפתרון Objectify (גרסה 6 ואילך) של Java. Objectify הוא API בקוד פתוח ל-Datastore שמספק רמה גבוהה יותר של הפשטה.
הבדלים בשימוש בזיכרון
בזמני ריצה מדור שני נרשם בסיס גבוה יותר של שימוש בזיכרון בהשוואה לזמני ריצה מדור ראשון. הסיבות לכך יכולות להיות מגוונות, למשל גרסאות שונות של תמונות בסיס והבדלים באופן שבו שני הדורות מחשבים את השימוש בזיכרון.
בסביבות זמן ריצה מהדור השני, השימוש בזיכרון של מופע מחושב כסכום של מה שתהליך האפליקציה צורך, ומספר קובצי האפליקציה שנשמרים במטמון באופן דינמי בזיכרון. כדי למנוע מצבים שבהם אפליקציות שדורשות הרבה זיכרון גורמות להשבתת מופעים בגלל חריגה ממגבלות הזיכרון, כדאי לשדרג לסוג מופע גדול יותר עם יותר זיכרון.
הבדלים בשימוש במעבד
בזמני ריצה מדור שני, יכול להיות שיהיה שימוש גבוה יותר במעבד בנקודת הבסיס אחרי הפעלה קרה של מופע. בהתאם להגדרת קנה המידה של האפליקציה, יכולות להיות לכך תופעות לוואי לא רצויות, כמו מספר מופעים גבוה מהצפוי אם האפליקציה מוגדרת להרחבה על סמך ניצול המעבד. כדי להימנע מהבעיה הזו, כדאי לבדוק את הגדרות קנה המידה של האפליקציה ולוודא שמספר המופעים מקובל.
הבדלים בכותרות הבקשה
סביבות זמן ריצה מהדור הראשון מאפשרות להעביר לאפליקציה כותרות של בקשות עם קווים תחתונים (למשל X-Test-Foo_bar). בסביבות זמן ריצה מהדור השני, Nginx מוצגת בארכיטקטורת המארח. כתוצאה מהשינוי הזה, סביבות זמן ריצה מהדור השני מוגדרות להסרה אוטומטית של כותרות עם קווים תחתונים (_). כדי למנוע בעיות באפליקציה, מומלץ להימנע משימוש בקווים תחתונים בכותרות של בקשות לאפליקציה.
גמישות המסגרת
סביבות זמן הריצה של Java מהדור השני לא כוללות מסגרת להצגת תוכן באינטרנט, אלא אם אתם משתמשים בשירותים מדור קודם שצורפו לחבילה. המשמעות היא שאפשר להשתמש במסגרת שאינה מבוססת על servlet. אם אתם משתמשים בחבילת השירותים מדור קודם, סביבות זמן הריצה של Java מהדור השני מספקות את מסגרת Jetty להצגת אינטרנט.
יש hello world דוגמאות לשימוש במסגרות פופולריות של Java לאינטרנט בGoogle Cloud מאגר GitHub:
העברה של קובצי XML לפורמטים של קובצי YAML
ה-CLI של gcloud לא תומך בפורמטים הבאים של קבצים:
cron.xmldatastore-index.xmldispatch.xmlqueue.xml
בדוגמאות הבאות מוסבר איך להעביר קובצי xml לקובצי yaml.
העברת הקבצים באופן אוטומטי
כדי להעביר את הקבצים ב-xml באופן אוטומטי:
צריך לוודא שמותקנת גרסה 226.0.0 ואילך של ה-CLI של gcloud. כדי לעדכן לגרסה האחרונה:
gcloud components updateלכל קובץ שרוצים להעביר, מציינים אחת מהפקודות המשניות הבאות (
cron-xml-to-yaml, datastore-indexes-xml-to-yaml,dispatch-xml-to-yaml, queue-xml-to-yaml) ואת שם הקובץ:gcloud beta app migrate-config queue-xml-to-yaml MY-QUEUE-XML-FILE.xmlלפני שפורסים את הקובץ המומר בסביבת הייצור, כדאי לבדוק אותו ידנית.
כדי לראות דוגמה להמרת קובץ
xmlל-yamlמוצלחת, אפשר לעבור לכרטיסיות העברה ידנית של קבצים.
העברת הקבצים באופן ידני
כדי להעביר ידנית את קובצי xml לקובצי yaml:
cron.yaml
יוצרים קובץ cron.yaml עם אובייקט cron שמכיל רשימה של אובייקטים, שלכל אחד מהם יש שדות שתואמים לכל אחד ממאפייני התג <cron> בקובץ cron.xml, כמו שמוצג בהמשך.
קובץ cron.yaml שהומר:
cron:
- url: '/recache'
schedule: 'every 2 minutes'
description: 'Repopulate the cache every 2 minutes'
- url: '/weeklyreport'
schedule: 'every monday 08:30'
target: 'version-2'
timezone: 'America/New_York'
description: 'Mail out a weekly report'
קובץ cron.xml מקורי:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/recache</url>
<description>Repopulate the cache every 2 minutes</description>
<schedule>every 2 minutes</schedule>
</cron>
<cron>
<url>/weeklyreport</url>
<description>Mail out a weekly report</description>
<schedule>every monday 08:30</schedule>
<timezone>America/New_York</timezone>
<target>version-2</target>
</cron>
</cronentries>
מידע נוסף מופיע בcron.yamlמאמרי העזרה.
dispatch.yaml
יוצרים קובץ dispatch.yaml עם אובייקט dispatch שמכיל רשימה של אובייקטים, שלכל אחד מהם יש שדות שתואמים לכל אחד מהמאפיינים של תג <dispatch> בקובץ dispatch.xml, כמו שמוצג בהמשך.
קובץ dispatch.yaml שהומר:
dispatch:
- url: '*/favicon.ico'
module: default
- url: 'simple-sample.uc.r.appspot.com/'
module: default
- url: '*/mobile/*'
module: mobile-frontend
קובץ dispatch.xml מקורי
<?xml version="1.0" encoding="UTF-8"?>
<dispatch-entries>
<dispatch>
<url>*/favicon.ico</url>
<module>default</module>
</dispatch>
<dispatch>
<url>simple-sample.uc.r.appspot.com/</url>
<module>default</module>
</dispatch>
<dispatch>
<url>*/mobile/*</url>
<module>mobile-frontend</module>
</dispatch>
</dispatch-entries>
מידע נוסף מופיע במאמרי העזרה בנושא dispatch.yaml.
index.yaml
יוצרים קובץ index.yaml עם אובייקט indexes שמכיל רשימה של אובייקטים, שלכל אחד מהם יש שדות שתואמים לכל אחד ממאפייני התג <datastore-index> בקובץ datastore-indexes.xml, כמו שמוצג בהמשך.
קובץ index.yaml שהומר:
indexes:
- ancestor: false
kind: Employee
properties:
- direction: asc
name: lastName
- direction: desc
name: hireDate
- ancestor: false
kind: Project
properties:
- direction: asc
name: dueDate
- direction: desc
name: cost
קובץ datastore-index.xml מקורי:
<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
autoGenerate="true">
<datastore-index kind="Employee" ancestor="false">
<property name="lastName" direction="asc" />
<property name="hireDate" direction="desc" />
</datastore-index>
<datastore-index kind="Project" ancestor="false">
<property name="dueDate" direction="asc" />
<property name="cost" direction="desc" />
</datastore-index>
</datastore-indexes>
מידע נוסף מופיע בindex.yamlמאמרי העזרה.
queue.yaml
יוצרים קובץ queue.yaml עם אובייקט queue שמכיל רשימה של אובייקטים, שלכל אחד מהם יש שדות שתואמים למאפיינים של תג <queue> בקובץ queue.xml, כמו שמוצג בהמשך.
קובץ queue.yaml שהומר:
queue:
- name: fooqueue
mode: push
rate: 1/s
retry_parameters:
task_retry_limit: 7
task_age_limit: 2d
- name: barqueue
mode: push
rate: 1/s
retry_parameters:
min_backoff_seconds: 10
max_backoff_seconds: 200
max_doublings: 0
קובץ queue.xml מקורי:
<queue-entries>
<queue>
<name>fooqueue</name>
<rate>1/s</rate>
<retry-parameters>
<task-retry-limit>7</task-retry-limit>
<task-age-limit>2d</task-age-limit>
</retry-parameters>
</queue>
<queue>
<name>barqueue</name>
<rate>1/s</rate>
<retry-parameters>
<min-backoff-seconds>10</min-backoff-seconds>
<max-backoff-seconds>200</max-backoff-seconds>
<max-doublings>0</max-doublings>
</retry-parameters>
</queue>
<queue-entries>