Java 8 telah mencapai akhir dukungan pada 31 Januari 2024. Aplikasi Java 8 Anda yang sudah ada akan terus berjalan dan menerima traffic. Namun, App Engine mungkin memblokir deployment ulang aplikasi yang menggunakan runtime setelah akhir tanggal dukungannya. Sebaiknya lakukan migrasi ke versi Java terbaru yang didukung menggunakan panduan di halaman ini.
Dengan bermigrasi ke runtime Java 11+, yang juga dikenal sebagai runtime Java generasi kedua, Anda dapat menggunakan fitur bahasa terbaru dan membangun aplikasi yang lebih portabel dengan kode idiomatis.
Memahami opsi migrasi Anda
Untuk mengurangi upaya dan kerumitan migrasi runtime, lingkungan standar App Engine memungkinkan Anda mengakses banyak layanan dan API lama yang dipaketkan, seperti Memcache, dalam runtime Java generasi kedua. Aplikasi Java Anda dapat memanggil API layanan yang dipaketkan melalui JAR App Engine API, dan mengakses sebagian besar kemampuan yang sama seperti pada runtime Java 8.
Anda juga memiliki opsi untuk menggunakan produk Google Cloud yang menawarkan fungsi serupa dengan layanan paket lama. Produk Google Cloud ini menyediakan Library Klien Cloud untuk Java yang idiomatis. Untuk paket layanan yang tidak tersedia sebagai produk terpisah di Google Cloud, seperti pemrosesan gambar, penelusuran, dan pesan, Anda dapat menggunakan penyedia pihak ketiga atau solusi lain yang disarankan.
Untuk mempelajari lebih lanjut cara bermigrasi ke layanan yang tidak dipaketkan, lihat Bermigrasi dari layanan paket.
Ada beberapa perbedaan dalam melakukan migrasi runtime, tergantung apakah Anda memilih untuk menggunakan layanan paket lama atau tidak:
Bermigrasi ke runtime Java 11+ dengan layanan yang dipaketkan | Bermigrasi ke runtime Java 11+ tanpa paket layanan |
---|---|
Akses layanan paket menggunakan JAR API App Engine. | Atau, gunakan produk Google Cloud atau layanan pihak ketiga yang direkomendasikan. |
Gunakan
Anda mungkin juga perlu mengonfigurasi file YAML tambahan, tergantung pada fitur yang digunakan aplikasi Anda. |
Gunakan
Anda mungkin juga perlu mengonfigurasi file YAML tambahan, tergantung pada fitur yang digunakan aplikasi Anda. |
Aplikasi di-deploy melalui Jetty. Menggunakan format WAR untuk mengemas aplikasi Anda. | Aplikasi di-deploy menggunakan server Anda sendiri. Gunakan format JAR untuk mengemas aplikasi Anda. Untuk mempelajari lebih lanjut cara mengonversi file WAR yang sudah ada menjadi JAR yang dapat dieksekusi, lihat Memaketkan ulang file WAR. |
Ringkasan proses migrasi
Berikut ini daftar beberapa perubahan yang mungkin harus Anda lakukan pada aplikasi App Engine Java 8 yang ada dan proses deployment agar dapat menggunakan runtime Java generasi kedua:
- Download Google Cloud CLI.
- Lakukan migrasi dari plugin Maven App Engine mandiri ke plugin Maven berbasis gcloud CLI atau plugin Gradle berbasis gcloud CLI.
- Instal JAR API App Engine jika Anda menggunakan layanan paket lama.
Perbedaan utama antara runtime Java 8 dan Java 11+
Berikut adalah ringkasan perbedaan antara runtime Java 8 dan Java 11+ di lingkungan standar App Engine:
Runtime Java 8 | Runtime Java 11+ | |
---|---|---|
Deployment server | Server di-deploy untuk Anda melalui Jetty | Jika aplikasi Anda tidak menggunakan layanan paket lama, Anda harus men-deploy server sendiri.1 |
Layanan paket lama App Engine | Tersedia | Tersedia |
Kemampuan menggunakan Library Klien Cloud untuk Java | Ya | Ya |
Dukungan Ekstensi bahasa dan library sistem | Ya | Ya |
Akses jaringan eksternal | Ya | Ya |
Akses sistem file | Akses baca/tulis ke /tmp
|
Akses baca/tulis ke /tmp
|
Runtime bahasa | Diubah untuk App Engine | Runtime open source yang tidak dimodifikasi |
Mekanisme isolasi | Sandbox container berbasis gVisor | Sandbox container berbasis gVisor |
Menguji dengan server pengembangan lokal | Didukung | Didukung |
Konfigurasi keamanan thread | Dapat ditentukan dalam file appengine-web.xml .
|
Tidak dapat ditentukan dalam file konfigurasi. Semua aplikasi dianggap aman untuk thread.3 |
Logging | Menggunakan java.util.logging. ConsoleHandler , yang menulis ke stderr dan mengosongkan aliran data setelah setiap pencatatan data. |
Cloud Logging Standar 2 |
Dukungan plugin DataNucleus 2.x | Didukung | Tidak didukung 4 |
Catatan:
Jika aplikasi Anda tidak menggunakan layanan paket versi lama, runtime Java generasi kedua dapat menjalankan framework Java apa pun selama Anda mengemas server web yang dikonfigurasi untuk merespons permintaan HTTP pada port yang ditentukan oleh variabel lingkungan
PORT
(direkomendasikan) atau di port 8080. Misalnya, runtime Java generasi kedua dapat menjalankan Spring Boot Uber JAR sebagaimana adanya. Untuk contoh lainnya, lihat bagian Fleksibilitas framework.Jika aplikasi Anda menggunakan layanan paket lama, App Engine akan men-deploy-nya menggunakan Jetty dengan cara yang sama seperti pada runtime Java 8.
Logging dalam runtime Java generasi kedua mengikuti standar logging di Cloud Logging. Pada runtime Java generasi kedua, log aplikasi tidak lagi dipaketkan dengan log permintaan, tetapi dipisahkan dalam catatan yang berbeda. Untuk mempelajari lebih lanjut cara membaca dan menulis log dalam runtime Java generasi kedua, lihat panduan logging.
Untuk mengonfigurasi aplikasi non-threadsafe di runtime Java generasi kedua, yang mirip dengan menyetel
<threadsafe>false</threadsafe>
di Java 8, tetapkan konkurensi maksimal ke 1 di fileapp.yaml
, atau fileappengine-web.xml
jika menggunakan layanan paket lama.Google tidak mendukung library DataNucleus di runtime generasi kedua. Versi DataNucleus yang lebih baru tidak kompatibel dengan versi yang digunakan di Java 8. Untuk mengakses Datastore, sebaiknya gunakan library klien mode Datastore atau solusi Objectify (versi 6 atau yang lebih baru) Java. Objectify adalah API open source untuk Datastore yang menyediakan tingkat abstraksi yang lebih tinggi.
Perbedaan penggunaan memori
Runtime generasi kedua mengalami dasar penggunaan memori yang lebih tinggi dibandingkan runtime generasi pertama. Hal ini disebabkan oleh beberapa faktor, seperti versi image dasar yang berbeda, dan perbedaan cara penghitungan penggunaan memori oleh kedua generasi.
Runtime generasi kedua menghitung penggunaan memori instance sebagai jumlah penggunaan proses aplikasi, dan jumlah file aplikasi yang di-cache secara dinamis dalam memori. Untuk menghindari aplikasi yang menggunakan banyak memori mengalami penonaktifan instance karena melebihi batas memori, upgrade ke class instance yang lebih besar dengan memori yang lebih besar.
Perbedaan penggunaan CPU
Runtime generasi kedua dapat melihat dasar penggunaan CPU yang lebih tinggi saat cold start instance. Bergantung pada konfigurasi penskalaan aplikasi, hal ini mungkin memiliki efek samping yang tidak diinginkan, seperti jumlah instance yang lebih tinggi daripada yang diperkirakan jika aplikasi dikonfigurasi untuk diskalakan berdasarkan penggunaan CPU. Untuk menghindari masalah ini, tinjau dan uji konfigurasi penskalaan aplikasi untuk memastikan jumlah instance dapat diterima.
Perbedaan header permintaan
Runtime generasi pertama memungkinkan header permintaan dengan garis bawah (misalnya, X-Test-Foo_bar
) diteruskan ke aplikasi. Runtime generasi kedua memperkenalkan Nginx ke dalam arsitektur host. Akibat perubahan
ini, runtime generasi kedua dikonfigurasi untuk otomatis menghapus
header dengan garis bawah (_
). Untuk mencegah masalah aplikasi, hindari penggunaan
garis bawah dalam header permintaan aplikasi.
Fleksibilitas framework
Runtime Java generasi kedua tidak menyertakan framework layanan web apa pun, kecuali jika Anda menggunakan layanan paket lama. Artinya, Anda dapat menggunakan framework selain framework berbasis servlet. Jika Anda menggunakan layanan paket lama, runtime Java generasi kedua akan menyediakan framework layanan web Jetty.
Ada hello world
contoh yang menggunakan framework web Java populer di
repositori GitHub Google Cloud:
Memigrasikan format file XML ke YAML
gcloud CLI tidak mendukung format file berikut:
cron.xml
datastore-index.xml
dispatch.xml
queue.xml
Contoh berikut menunjukkan cara memigrasikan file xml
ke
file yaml
.
Memigrasikan file secara otomatis
Untuk memigrasikan file xml
secara otomatis:
Anda harus memiliki gcloud CLI versi 226.0.0 atau yang lebih baru. Untuk mengupdate ke versi terbaru:
gcloud components update
Untuk setiap file yang ingin dimigrasikan, tentukan salah satu subperintah berikut (
cron-xml-to-yaml
,datastore-indexes-xml-to-yaml
,dispatch-xml-to-yaml
,queue-xml-to-yaml
) dan nama file:gcloud beta app migrate-config queue-xml-to-yaml MY-QUEUE-XML-FILE.xml
Periksa kembali file yang dikonversi secara manual sebelum men-deploy ke produksi.
Untuk mengetahui contoh konversi file
xml
keyaml
yang berhasil, lihat tab Memigrasikan file secara manual.
Memigrasikan file secara manual
Untuk memigrasikan file xml
secara manual ke file yaml
:
cron.yaml
Buat file cron.yaml
dengan objek cron
yang berisi daftar objek,
masing-masing dengan kolom yang sesuai dengan setiap atribut tag <cron>
dalam
file cron.xml
, sebagai yang ditunjukkan di bawah ini.
File cron.yaml
yang dikonversi:
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'
File cron.xml
asli:
<?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>
Untuk informasi selengkapnya, lihat dokumentasi referensi cron.yaml
.
dispatch.yaml
Buat file dispatch.yaml
dengan objek dispatch
yang berisi daftar
objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <dispatch>
dalam file dispatch.xml
, sebagai yang ditunjukkan di bawah ini.
File dispatch.yaml
yang dikonversi:
dispatch:
- url: '*/favicon.ico'
module: default
- url: 'simple-sample.uc.r.appspot.com/'
module: default
- url: '*/mobile/*'
module: mobile-frontend
File dispatch.xml
asli
<?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>
Untuk informasi selengkapnya, lihat dokumentasi referensi dispatch.yaml
index.yaml
Buat file index.yaml
dengan objek indexes
yang berisi daftar
objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <datastore-index>
dalam file datastore-indexes.xml
, sebagai yang ditunjukkan di bawah ini.
File index.yaml
yang dikonversi:
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
File datastore-index.xml
asli:
<?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>
Untuk informasi selengkapnya, lihat dokumentasi referensi index.yaml
.
queue.yaml
Buat file queue.yaml
dengan objek queue
yang berisi daftar
objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <queue>
dalam file queue.xml
, sebagai yang ditunjukkan di bawah ini.
File queue.yaml
yang dikonversi:
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
File queue.xml
asli:
<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>