Rangkaian codelab ini (tutorial praktik mandiri) bertujuan untuk membantu developer Google App Engine (Standar) memodernisasi aplikasi mereka dengan memandu mereka melalui serangkaian migrasi. Langkah yang paling signifikan adalah beralih dari layanan paket runtime asli karena runtime generasi berikutnya lebih fleksibel, sehingga memberikan opsi layanan yang lebih beragam kepada pengguna. Peralihan ke runtime generasi baru memungkinkan Anda berintegrasi dengan produk Google Cloud dengan lebih mudah, menggunakan berbagai layanan yang didukung, dan mendukung rilis bahasa saat ini.
Codelab ini membantu pengguna melakukan migrasi dari tugas push App Engine dan taskqueue
API/library-nya ke Cloud Tasks. Jika aplikasi Anda tidak menggunakan Task Queues, Anda dapat menggunakan codelab ini sebagai latihan untuk mempelajari cara memigrasikan tugas push App Engine ke Cloud Tasks.
Anda akan mempelajari cara
- Melakukan migrasi dari App Engine
taskqueue
ke Cloud Tasks - Membuat tugas push dengan Cloud Tasks
- Melakukan migrasi dari App Engine
ndb
ke Cloud NDB (sama dengan Modul 2)
Yang akan Anda perlukan
- Project Google Cloud Platform dengan:
- Keterampilan Python dasar
- Pengetahuan perintah Linux umum yang berfungsi
- Pengetahuan dasar tentang mengembangkan dan men-deploy aplikasi App Engine
- Anda disarankan untuk menyelesaikan codelab Modul 7 sebelum memulai ini (Modul 8).
- Aplikasi App Engine Modul 7 yang berfungsi
Survei
Bagaimana Anda akan menggunakan codelab ini?
Karena kami menambahkan tugas push App Engine ke aplikasi sampel di codelab (Module 7) sebelumnya, sekarang kita dapat memigrasikannya ke Cloud Tasks. Migrasi dalam tutorial ini memaparkan langkah-langkah utama berikut:
- Penyiapan/Prakerja
- Memperbarui file konfigurasi
- Memperbarui aplikasi utama
Sebelum memulai bagian utama tutorial, mari kita siapkan project, dapatkan kodenya, lalu deploy aplikasi dasar pengukuran sehingga kita tahu bahwa kita memulai dengan kode yang berfungsi.
1. Siapkan project
Sebaiknya gunakan kembali project yang sama dengan yang Anda gunakan untuk menyelesaikan codelab Modul 7. Atau, Anda dapat membuat project baru atau menggunakan kembali project lain yang sudah ada. Pastikan project memiliki akun penagihan yang aktif dan App Engine (aplikasi) diaktifkan.
2. Dapatkan aplikasi contoh dasar pengukuran
Salah satu prasyarat untuk codelab ini adalah memiliki aplikasi contoh Modul 7 yang berfungsi. Jika Anda tidak memilikinya, sebaiknya selesaikan tutorial Modul 7 (link di atas) sebelum melanjutkan ke sini. Jika sudah terbiasa dengan kontennya, Anda bisa memulai dengan mengambil kode Modul 7 di bawah.
Baik Anda menggunakan kode Anda atau kode kami, kode Modul 7 adalah tempat kita akan memulai (START). Codelab Modul 2 ini akan memandu Anda melalui setiap langkah, dan setelah selesai, kode akan menyerupai kode pada titik FINISH (termasuk port opsional dari Python 2 hingga 3).
- START: Repo Modul 7
- FINISH: Repo Modul 8
- Seluruh repo (clone atau download ZIP)
Direktori file Modul 7 (milik Anda atau milik kami) akan terlihat seperti ini:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Jika sudah menyelesaikan tutorial Modul 7, Anda juga akan memiliki folder lib
dengan Flask dan dependensinya.
3. Deploy (ulang) aplikasi Modul 7
Langkah prakerja yang tersisa untuk dijalankan sekarang:
- Biasakan kembali diri Anda dengan alat command-line
gcloud
(jika perlu) - Deploy (ulang) kode Modul 7 ke App Engine (jika perlu)
Setelah Anda berhasil menjalankan langkah-langkah tersebut dan mengonfirmasikan operasinya, kita akan melanjutkan tutorial ini, dimulai dengan file konfigurasi.
requirements.txt
requirements.txt
dari Modul 7 hanya mencantumkan Flask sebagai paket wajib. Cloud NDB dan Cloud Tasks memiliki library klien sendiri, jadi di langkah ini, tambahkan paket tersebut ke requirements.txt
agar terlihat seperti ini:
Flask==1.1.2
google-cloud-ndb==1.7.1
google-cloud-tasks==1.5.0
Sebaiknya gunakan versi terbaru dari setiap library; nomor versi di atas adalah yang terbaru untuk Python 2 pada saat penulisan tutorial ini. (Paket setara Python 3 kemungkinan akan berada pada versi yang lebih tinggi.) Kode dalam folder repo FINISH lebih sering diperbarui dan mungkin memiliki rilis baru, meskipun kecil kemungkinan untuk library Python 2 yang biasanya dibekukan.
app.yaml
Lihat library bawaan grpcio
dan setuptools
di app.yaml
pada bagian libraries
:
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
appengine_config.py
Perbarui appengine_config.py
untuk menggunakan pkg_resources
guna mengikat library bawaan tersebut ke library pihak ke-3 yang disalin seperti Flask dan library klien Google Cloud:
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)
Hanya ada satu file aplikasi, main.py
, sehingga semua perubahan di bagian ini hanya memengaruhi file tersebut.
Perbarui impor dan inisialisasi
Aplikasi kami saat ini menggunakan library google.appengine.api.taskqueue
dan google.appengine.ext.ndb
bawaan:
- SEBELUM:
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
Ganti keduanya dengan google.cloud.ndb
dan google.cloud.tasks
. Selain itu, Cloud Tasks mengharuskan Anda melakukan enkode JSON terhadap payload tugas, sehingga juga mengimpor json
. Setelah selesai, berikut ini tampilan bagian import
dari main.py
:
- SETELAH:
from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
from google.cloud import ndb, tasks
Lakukan Migrasi ke Cloud Tasks (dan Cloud NDB)
- SEBELUM:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
Tidak ada perubahan pada store_visit()
selain yang Anda lakukan di Modul 2: tambahkan pengelola konteks ke semua akses Datastore. Hal ini disediakan dalam bentuk pemindahan pembuatan Entitas Visit
baru yang digabungkan di pernyataan with
.
- SETELAH:
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 Tasks saat ini mengharuskan App Engine diaktifkan untuk project Google Cloud agar Anda dapat menggunakannya (meskipun Anda tidak memiliki kode App Engine), jika tidak, task queue tidak akan berfungsi. (Lihat bagian ini di dokumen untuk informasi selengkapnya.) Cloud Tasks mendukung tugas yang berjalan di App Engine ("target" App Engine), tetapi juga dapat dijalankan di endpoint HTTP (target HTTP) dengan alamat IP publik, seperti Cloud Functions, Cloud Run, GKE, Compute Engine, atau bahkan server web lokal. Aplikasi sederhana kami menggunakan target App Engine untuk tugas.
Beberapa penyiapan diperlukan untuk menggunakan Cloud NDB dan Cloud Tasks. Di bagian atas main.py
pada inisialisasi Flask, lakukan inisialisasi Cloud NDB dan Cloud Tasks. Juga tentukan beberapa konstanta yang menunjukkan tempat tugas push Anda akan dieksekusi.
app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()
PROJECT_ID = 'PROJECT_ID' # replace w/your own
REGION = 'REGION' # replace w/your own
QUEUE_NAME = 'default' # replace w/your own if desired
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION, QUEUE_NAME)
Setelah membuat task queue, isi PROJECT_ID
project Anda, REGION
tempat tugas akan berjalan (harus sama dengan region App Engine), dan nama push queue Anda. App Engine menampilkan queue "default
", jadi kita akan menggunakan nama tersebut (tetapi Anda tidak harus).
Queue default
bersifat khusus dan dibuat secara otomatis dalam situasi tertentu, salah satunya adalah saat menggunakan App Engine API, jadi jika Anda menggunakan (kembali) project yang sama dengan Modul 7, default
akan sudah ada. Namun, jika membuat project baru khusus untuk Modul 8, Anda harus membuat default
secara manual. Info selengkapnya tentang queue default
dapat ditemukan di dokumentasi queue.yaml
.
Tujuan ts_client.queue_path()
adalah membuat "nama jalur yang sepenuhnya memenuhi syarat" (QUEUE_PATH
) milik task queue yang diperlukan untuk membuat tugas. Selain itu, struktur JSON yang menentukan parameter tugas juga diperlukan:
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
Apa yang Anda lihat di atas?
- Berikan informasi target tugas:
- Untuk target App Engine, tentukan
app_engine_http_request
sebagai jenis permintaan danrelative_uri
adalah pengendali tugas App Engine. - Untuk target HTTP, gunakan
http_request
danurl
.
- Untuk target App Engine, tentukan
body
: parameter yang dienkode string JSON dan Unicode yang akan dikirim ke tugas (push)- Tentukan kejelasan header
Content-Type
yang dienkode JSON
Lihat dokumentasi untuk info selengkapnya tentang opsi Anda di sini.
Setelah penyiapan selesai, perbarui fetch_visits()
. Berikut ini tampilannya dari tutorial sebelumnya:
- SEBELUM:
def fetch_visits(limit):
'get most recent visits and 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 (v.to_dict() for v in data), oldest_str
Pembaruan yang diperlukan:
- Beralih dari App Engine
ndb
ke Cloud NDB - Kode baru untuk mengekstrak stempel waktu kunjungan terlama ditampilkan
- Menggunakan Cloud Tasks untuk membuat tugas baru, bukan App Engine
taskqueue
Seperti inilah tampilan fetch_visits()
baru Anda:
- SETELAH:
def fetch_visits(limit):
'get most recent visits and 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
Meringkas pembaruan kode:
- Beralih ke Cloud NDB berarti memindahkan kode Datastore dalam pernyataan
with
- Beralih ke Cloud Tasks berarti menggunakan
ts_client.create_task()
, bukantaskqueue.add()
- Teruskan jalur lengkap queue dan payload
task
(dijelaskan sebelumnya)
Perbarui pengendali tugas (push)
Ada sangat sedikit perubahan yang perlu dilakukan pada fungsi pengendali tugas (push).
- SEBELUM:
@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
Satu-satunya hal yang perlu dilakukan, adalah menempatkan semua akses Datastore dalam pernyataan with
pengelola konteks, baik permintaan kueri maupun penghapusan. Dengan mempertimbangkan hal ini, perbarui pengendali trim()
Anda seperti ini:
- SETELAH:
@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
Tidak ada perubahan pada templates/index.html
dalam hal ini atau dalam codelab berikutnya.
Deploy aplikasi
Periksa kembali semua perubahan, yang dikompilasi kode Anda, dan deploy ulang. Konfirmasi bahwa aplikasi (masih) berfungsi. Anda akan mendapatkan output yang sama dengan output dari Modul 7. Anda baru saja melakukan perbaikan, jadi seharusnya semuanya tetap berfungsi seperti yang diharapkan.
Jika Anda langsung masuk ke dalam tutorial ini tanpa melakukan codelab Modul 7, aplikasi itu sendiri tidak akan berubah. Aplikasi mendaftar semua kunjungan ke halaman web utama (/
) dan tampak seperti ini setelah Anda mengunjungi situs cukup waktu dan memberi tahu Anda bahwa situs tersebut telah menghapus semua kunjungan yang lebih lama dari tanggal sepuluh:
Ini mengakhiri codelab ini. Kode Anda sekarang seharusnya cocok dengan yang ada di repo Modul 8. Selamat karena telah menyelesaikan migrasi tugas push yang paling penting! Modul 9 (link codelab di bawah) bersifat opsional, membantu pengguna berpindah ke Python 3 dan Cloud Datastore.
Opsional: Pembersihan
Bagaimana dengan pembersihan agar tidak ditagih hingga Anda siap untuk beralih ke codelab migrasi berikutnya? Sebagai developer yang sudah ada, Anda mungkin sudah mengetahui yang terbaru tentang informasi harga App Engine.
Opsional: Nonaktifkan aplikasi
Jika Anda belum siap melanjutkan ke tutorial berikutnya, nonaktifkan aplikasi untuk menghindari tagihan. Jika sudah siap untuk beralih ke codelab berikutnya, Anda dapat mengaktifkannya kembali. Meskipun dinonaktifkan, aplikasi tidak akan mendapatkan traffic yang dikenakan biaya, namun hal lain yang dapat ditagih adalah penggunaan Datastore jika melebihi kuota gratis, jadi cukup hapus hingga berada di bawah batas tersebut.
Di sisi lain, jika Anda tidak akan melanjutkan migrasi dan ingin menghapus semuanya, Anda dapat mematikan project.
Langkah berikutnya
Selain tutorial ini, langkah selanjutnya adalah Modul 9 dan codelab-nya serta melakukan porting ke Python 3. Ini sedikit opsional karena tidak semua orang siap untuk langkah tersebut. Ada juga port opsional dari Cloud NDB ke Cloud Datastore - opsi ini sudah pasti bersifat opsional dan hanya bagi mereka yang ingin keluar dari NDB dan menggabungkan kode yang menggunakan Cloud Datastore. Migrasi tersebut sama dengan codelab migrasi Modul 3.
- Modul 9 Bermigrasi dari Python 2 ke 3 dan Cloud NDB ke Cloud Datastore
- Porting modul migrasi opsional ke Python 3
- Juga mencakup migrasi opsional dari Cloud NDB ke Cloud Datastore (sama seperti Modul 3), dan
- Migrasi kecil dari Cloud Tasks v1 ke v2 (karena library kliennya dibekukan untuk Python 2)
- Modul 4: Bermigrasi ke Cloud Run dengan Docker
- Build aplikasi dalam container untuk dijalankan di Cloud Run dengan Docker
- Migrasi ini memungkinkan Anda untuk tetap menggunakan Python 2.
- Modul 5: Melakukan Migrasi ke Cloud Run dengan Cloud Buildpacks
- Build aplikasi dalam container untuk dijalankan di Cloud Run dengan Cloud Buildpacks
- Anda tidak perlu mengetahui apa pun tentang Docker, container, atau
Dockerfile
. - Mengharuskan aplikasi Anda untuk sudah bermigrasi ke Python 3 (Buildpacks tidak mendukung Python 2)
- Modul 6: Melakukan Migrasi ke Cloud Firestore
- Melakukan migrasi ke Cloud Firestore untuk mengakses fitur Firebase
- Meskipun Cloud Firestore mendukung Python 2, codelab ini hanya tersedia di Python 3.
Masalah/masukan codelab modul migrasi App Engine
Jika Anda menemukan masalah dengan codelab ini, telusuri masalah Anda terlebih dahulu sebelum mengajukan masalah. Link untuk menelusuri dan membuat masalah baru:
Resource migrasi
Link ke folder repo untuk Modul 7 (START) dan Modul 8 (FINISH) dapat ditemukan pada tabel di bawah. Link tersebut juga dapat diakses dari repo untuk semua migrasi codelab App Engine yang dapat Anda clone atau download file ZIP.
Codelab | Python 2 | Python 3 |
(T/A) | ||
Modul 8 | (T/A) |
Resource App Engine
Berikut adalah resource tambahan terkait migrasi khusus ini:
- Referensi App Engine
ndb
dan Cloud NDB - Referensi App Engine
taskqueue
dan Cloud Tasks - Melakukan migrasi ke Python 3 dan runtime GAE generasi berikutnya
- Umum