Bermigrasi dari tugas pull Task Queue App Engine ke Cloud Pub/Sub (Modul 19)

1. Ringkasan

Serangkaian codelab Serverless Migration Station (tutorial praktik mandiri) dan video terkait bertujuan untuk membantu developer serverless Google Cloud memodernisasi aplikasi mereka dengan memandu mereka melalui satu atau beberapa migrasi, terutama beralih dari layanan lama. Dengan melakukannya, aplikasi Anda akan lebih portabel dan Anda akan memiliki lebih banyak opsi dan fleksibilitas, sehingga Anda dapat berintegrasi dengan dan mengakses berbagai produk Cloud serta mengupgrade ke rilis bahasa yang lebih baru dengan lebih mudah. Meskipun awalnya berfokus pada pengguna Cloud paling awal, terutama developer App Engine (lingkungan standar), seri ini cukup luas untuk mencakup platform serverless lainnya seperti Cloud Functions dan Cloud Run, atau di tempat lain jika berlaku.

Tujuan codelab ini adalah untuk menunjukkan kepada developer App Engine Python 2 cara bermigrasi dari tugas pull App Engine Task Queue ke Cloud Pub/Sub. Ada juga migrasi implisit dari App Engine NDB ke Cloud NDB untuk akses Datastore (terutama dibahas di Modul 2) serta upgrade ke Python 3.

Dalam Modul 18, Anda akan mempelajari cara menambahkan penggunaan tugas pull di aplikasi Anda. Dalam modul ini, Anda akan mengambil aplikasi Modul 18 yang telah selesai dan memigrasikan penggunaan tersebut ke Cloud Pub/Sub. Pengguna yang menggunakan Task Queues untuk tugas push akan bermigrasi ke Cloud Tasks dan harus melihat Modul 7-9.

Anda akan mempelajari cara

Yang Anda butuhkan

Survei

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana penilaian Anda terhadap pengalaman dengan Python?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud?

Pemula Menengah Mahir

2. Latar belakang

App Engine Task Queue mendukung tugas push dan pull. Untuk meningkatkan portabilitas aplikasi, Google Cloud merekomendasikan migrasi dari layanan paket lama seperti Task Queue ke layanan mandiri Cloud atau layanan setara pihak ketiga lainnya.

Modul 7-9 membahas migrasi tugas push, sedangkan Modul 18-19 berfokus pada migrasi tugas pull. Meskipun Cloud Tasks lebih cocok dengan tugas push Task Queue, Pub/Sub tidak terlalu cocok dengan tugas pull Task Queue.

Pub/Sub memiliki lebih banyak fitur daripada fungsi pull yang disediakan oleh Task Queue. Misalnya, Pub/Sub juga memiliki fungsi push, tetapi Cloud Tasks lebih seperti tugas push Task Queue, sehingga push Pub/Sub tidak tercakup dalam Modul Migrasi mana pun. Codelab Modul 19 ini menunjukkan cara mengganti mekanisme antrean dari pull queue Task Queue ke Pub/Sub serta melakukan migrasi dari App Engine NDB ke Cloud NDB untuk akses Datastore, dengan mengulangi migrasi Modul 2.

Meskipun kode Modul 18 "diiklankan" sebagai aplikasi contoh Python 2, sumbernya sendiri kompatibel dengan Python 2 dan 3, dan tetap seperti itu bahkan setelah bermigrasi ke Cloud Pub/Sub (dan Cloud NDB) di Modul 19 ini.

Tutorial ini mencakup langkah-langkah berikut:

  1. Penyiapan/Prakerja
  2. Update konfigurasi
  3. Mengubah kode aplikasi

3. Penyiapan/Prakerja

Bagian ini menjelaskan cara:

  1. Menyiapkan project Cloud
  2. Dapatkan aplikasi contoh dasar pengukuran
  3. Deploy (ulang) dan validasi aplikasi dasar pengukuran
  4. Mengaktifkan layanan/API Google Cloud baru

Langkah-langkah ini memastikan Anda memulai dengan kode yang berfungsi dan siap untuk dimigrasikan ke layanan Cloud.

1. Siapkan project

Jika Anda telah menyelesaikan codelab Modul 18, gunakan kembali project (dan kode) yang sama. Atau, buat project baru atau gunakan kembali project lain yang sudah ada. Pastikan project memiliki akun penagihan yang aktif dan aplikasi App Engine yang diaktifkan. Temukan ID project Anda karena Anda harus menyediakannya selama codelab ini, dengan menggunakannya setiap kali Anda menemukan variabel PROJECT_ID.

2. Dapatkan aplikasi contoh dasar pengukuran

Salah satu prasyaratnya adalah aplikasi App Engine Modul 18 yang berfungsi, jadi selesaikan codelabnya (direkomendasikan; link di atas) atau salin kode Modul 18 dari repo. Baik Anda menggunakan kode Anda atau kode kami, di sinilah kita akan memulai ("START"). Codelab ini akan memandu Anda melakukan migrasi, yang diakhiri dengan kode yang menyerupai kode di folder repo Modul 19 ("FINISH").

Terlepas dari aplikasi Modul 18 yang Anda gunakan, folder akan terlihat seperti di bawah, mungkin dengan folder lib juga:

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

3. Deploy (ulang) dan validasi aplikasi dasar pengukuran

Lakukan langkah-langkah berikut untuk men-deploy aplikasi Module 18:

  1. Hapus folder lib jika ada dan jalankan pip install -t lib -r requirements.txt untuk mengisi kembali lib. Anda mungkin perlu menggunakan pip2 jika Anda telah menginstal Python 2 dan 3 di mesin pengembangan.
  2. Pastikan Anda telah menginstal dan menginisialisasi alat command line gcloud serta meninjau penggunaannya.
  3. (opsional) Tetapkan project Cloud Anda dengan gcloud config set project PROJECT_ID jika Anda tidak ingin memasukkan PROJECT_ID dengan setiap perintah gcloud yang Anda keluarkan.
  4. Men-deploy aplikasi contoh dengan gcloud app deploy
  5. Konfirmasi bahwa aplikasi berjalan seperti yang diharapkan tanpa masalah. Jika Anda telah menyelesaikan codelab Modul 18, aplikasi akan menampilkan pengunjung teratas beserta kunjungan terbaru (seperti yang diilustrasikan di bawah). Jika tidak, mungkin tidak ada jumlah pengunjung yang dapat ditampilkan.

b667551dcbab1a09.png

Sebelum memigrasikan aplikasi contoh Modul 18, Anda harus mengaktifkan layanan Cloud yang akan digunakan oleh aplikasi yang dimodifikasi terlebih dahulu.

4. Mengaktifkan layanan/API Google Cloud baru

Aplikasi lama menggunakan layanan paket App Engine yang tidak memerlukan penyiapan tambahan, tetapi layanan Cloud mandiri memerlukannya, dan aplikasi yang diupdate akan menggunakan Cloud Pub/Sub dan Cloud Datastore (melalui library klien Cloud NDB). App Engine dan kedua Cloud API memiliki kuota paket "Selalu Gratis", dan selama Anda tidak melebihi batas tersebut, Anda tidak akan dikenai biaya saat menyelesaikan tutorial ini. Cloud API dapat diaktifkan dari Konsol Cloud atau dari command line, bergantung pada preferensi Anda.

Dari Cloud Console

Buka halaman Library API Manager (untuk project yang benar) di Konsol Cloud, lalu telusuri Cloud Datastore API dan Cloud Pub/Sub API menggunakan kotak penelusuran di tengah halaman:

c7a740304e9d35b.png

Klik tombol Aktifkan untuk setiap API secara terpisah—Anda mungkin diminta untuk memberikan informasi penagihan. Misalnya, berikut halaman Library API Cloud Pub/Sub:

1b6c0a2a73124f6b.jpeg

Dari command line

Meskipun secara visual memungkinkan API dari konsol, beberapa orang lebih memilih command line. Jalankan perintah gcloud services enable pubsub.googleapis.com datastore.googleapis.com untuk mengaktifkan kedua API secara bersamaan:

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

Anda mungkin akan diminta memasukkan informasi penagihan. Jika Anda ingin mengaktifkan Cloud API lainnya dan ingin mengetahui URI-nya, URI tersebut dapat ditemukan di bagian bawah halaman library setiap API. Misalnya, amati pubsub.googleapis.com sebagai "Nama layanan" di bagian bawah halaman Pub/Sub tepat di atas.

Setelah langkah-langkah selesai, project Anda akan dapat mengakses API. Sekarang saatnya mengupdate aplikasi untuk menggunakan API tersebut.

4. Membuat resource Pub/Sub

Merangkum urutan alur kerja Task Queue dari Modul 18:

  1. Modul 18 menggunakan file queue.yaml untuk membuat pull queue bernama pullq.
  2. Aplikasi menambahkan tugas ke pull queue untuk melacak pengunjung.
  3. Tugas akhirnya diproses oleh worker, yang di-lease selama jangka waktu tertentu (satu jam).
  4. Tugas dijalankan untuk menghitung jumlah pengunjung terbaru.
  5. Tugas akan dihapus dari antrean setelah selesai.

Anda akan mereplikasi alur kerja serupa dengan Pub/Sub. Bagian berikutnya memperkenalkan terminologi dasar Pub/Sub, dengan tiga cara berbeda untuk membuat resource Pub/Sub yang diperlukan.

Terminologi App Engine Task Queue (pull) vs. Cloud Pub/Sub

Beralih ke Pub/Sub memerlukan sedikit penyesuaian pada kosakata Anda. Di bawah ini adalah kategori utama beserta istilah yang relevan dari kedua produk. Tinjau juga panduan migrasi yang menampilkan perbandingan serupa.

  • Struktur data antrean: Dengan Task Queue, data masuk ke pull queue; dengan Pub/Sub, data masuk ke topik.
  • Unit data dalam antrean: Tugas pull dengan Task Queue disebut pesan dengan Pub/Sub.
  • Pemroses data: Dengan Task Queue, worker mengakses tugas pull; dengan Pub/Sub, Anda memerlukan langganan/pelanggan untuk menerima pesan
  • Ekstraksi data: Menyewa tugas pull sama dengan menarik pesan dari topik (melalui langganan).
  • Pembersihan/penyelesaian: Menghapus tugas Task Queue dari pull queue setelah Anda selesai sama dengan mengonfirmasi pesan Pub/Sub

Meskipun produk antrean berubah, alur kerjanya tetap relatif sama:

  1. Daripada antrean pull, aplikasi menggunakan topik bernama pullq.
  2. Daripada menambahkan tugas ke pull queue, aplikasi mengirim pesan ke topik (pullq).
  3. Daripada menyewa tugas dari pull queue, pelanggan bernama worker mengambil pesan dari topik pullq.
  4. Aplikasi memproses payload pesan, meningkatkan jumlah pengunjung di Datastore.
  5. Daripada menghapus tugas dari antrean tarik, aplikasi mengonfirmasi pesan yang diproses.

Dengan Task Queue, penyiapan melibatkan pembuatan pull queue. Dengan Pub/Sub, penyiapan memerlukan pembuatan topik dan langganan. Di Modul 18, kita memproses queue.yaml di luar eksekusi aplikasi; sekarang hal yang sama harus dilakukan dengan Pub/Sub.

Ada tiga opsi untuk membuat topik dan langganan:

  1. Dari Konsol Cloud
  2. Dari command line, atau
  3. Dari kode (skrip Python singkat)

Pilih salah satu opsi di bawah dan ikuti petunjuk yang sesuai untuk membuat resource Pub/Sub Anda.

Dari Konsol Cloud

Untuk membuat topik dari Konsol Cloud, ikuti langkah-langkah berikut:

  1. Buka halaman Topik Pub/Sub di Konsol Cloud.
  2. Klik Create topic di bagian atas; jendela dialog baru akan terbuka (lihat gambar di bawah)
  3. Di kolom Topic ID, masukkan pullq.
  4. Batalkan pilihan semua opsi yang dicentang, lalu pilih Kunci enkripsi yang dikelola Google.
  5. Klik tombol Buat topik.

Berikut tampilan dialog pembuatan topik:

a05cfdbf64571ceb.png

Setelah memiliki topik, Anda harus membuat langganan untuk topik tersebut:

  1. Buka halaman Pub/Sub Subscriptions di Konsol Cloud.
  2. Klik Buat langganan di bagian atas (lihat gambar di bawah).
  3. Masukkan worker di kolom ID Langganan.
  4. Pilih pullq dari menu tarik-turun Pilih topik Cloud Pub/Sub, dengan mencatat "nama jalur yang sepenuhnya memenuhi syarat", misalnya, projects/PROJECT_ID/topics/pullq
  5. Untuk Jenis pengiriman, pilih Tarik.
  6. Biarkan semua opsi lainnya seperti apa adanya, lalu klik tombol Create.

Berikut tampilan layar pembuatan langganan:

c5444375c20b0618.jpeg

Anda juga dapat membuat langganan dari halaman Topics—"pintasan" ini mungkin berguna bagi Anda untuk membantu mengaitkan topik dengan langganan. Untuk mempelajari lebih lanjut cara membuat langganan, lihat dokumentasi.

Dari command line

Pengguna Pub/Sub dapat membuat topik dan langganan dengan perintah gcloud pubsub topics create TOPIC_ID dan gcloud pubsub subscriptions create SUBSCRIPTION_ID --topic=TOPIC_ID. Menjalankan perintah ini dengan TOPIC_ID pullq dan SUBSCRIPTION_ID worker akan menghasilkan output berikut untuk project PROJECT_ID:

$ gcloud pubsub topics create pullq
Created topic [projects/PROJECT_ID/topics/pullq].

$ gcloud pubsub subscriptions create worker --topic=pullq
Created subscription [projects/PROJECT_ID/subscriptions/worker].

Lihat juga halaman ini dalam dokumentasi Panduan memulai. Penggunaan command line dapat menyederhanakan alur kerja saat topik dan langganan dibuat secara rutin, dan perintah tersebut dapat digunakan dalam skrip shell untuk tujuan ini.

Dari kode (skrip Python singkat)

Cara lain untuk mengotomatiskan pembuatan topik dan langganan adalah dengan menggunakan Pub/Sub API dalam kode sumber. Di bawah ini adalah kode untuk skrip maker.py di folder repo Modul 19.

from __future__ import print_function
import google.auth
from google.api_core import exceptions
from google.cloud import pubsub

_, PROJECT_ID = google.auth.default()
TOPIC = 'pullq'
SBSCR = 'worker'
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)

def make_top():
    try:
        top = ppc_client.create_topic(name=TOP_PATH)
        print('Created topic %r (%s)' % (TOPIC, top.name))
    except exceptions.AlreadyExists:
        print('Topic %r already exists at %r' % (TOPIC, TOP_PATH))

def make_sub():
    try:
        sub = psc_client.create_subscription(name=SUB_PATH, topic=TOP_PATH)
        print('Subscription created %r (%s)' % (SBSCR, sub.name))
    except exceptions.AlreadyExists:
        print('Subscription %r already exists at %r' % (SBSCR, SUB_PATH))
    try:
        psc_client.close()
    except AttributeError:  # special Py2 handler for grpcio<1.12.0
        pass

make_top()
make_sub()

Menjalankan skrip ini akan menghasilkan output yang diharapkan (asalkan tidak ada error):

$ python3 maker.py
Created topic 'pullq' (projects/PROJECT_ID/topics/pullq)
Subscription created 'worker' (projects/PROJECT_ID/subscriptions/worker)

Memanggil API untuk membuat resource yang sudah ada akan menghasilkan pengecualian google.api_core.exceptions.AlreadyExists yang ditampilkan oleh library klien, yang ditangani dengan baik oleh skrip:

$ python3 maker.py
Topic 'pullq' already exists at 'projects/PROJECT_ID/topics/pullq'
Subscription 'worker' already exists at 'projects/PROJECT_ID/subscriptions/worker'

Jika Anda baru menggunakan Pub/Sub, lihat laporan resmi arsitektur Pub/Sub untuk mendapatkan insight tambahan.

5. Update konfigurasi

Perubahan konfigurasi mencakup perubahan berbagai file konfigurasi serta pembuatan yang setara dengan pull queue App Engine, tetapi dalam ekosistem Cloud Pub/Sub.

Hapus queue.yaml

Kita tidak lagi menggunakan Task Queue, jadi hapus queue.yaml karena Pub/Sub tidak menggunakan file ini. Daripada membuat pull queue, Anda akan membuat topikPub/Sub (dan langganan).

requirements.txt

Tambahkan google-cloud-ndb dan google-cloud-pubsub ke requirements.txt untuk bergabung ke flask dari Modul 18. requirements.txt Modul 19 yang telah diupdate sekarang akan terlihat seperti ini:

flask
google-cloud-ndb
google-cloud-pubsub

File requirements.txt ini tidak memiliki nomor versi, yang berarti versi terbaru akan dipilih. Jika ada ketidakcocokan, ikuti praktik standar penggunaan nomor versi untuk mengunci versi aplikasi yang berfungsi.

app.yaml

Perubahan pada app.yaml berbeda-beda, bergantung pada apakah Anda tetap menggunakan Python 2 atau mengupgrade ke Python 3.

Python 2

Pembaruan requirements.txt di atas menambahkan penggunaan library klien Google Cloud. Hal ini memerlukan dukungan tambahan dari App Engine, yaitu beberapa library bawaan, setuptools, dan grpcio. Penggunaan library bawaan memerlukan bagian libraries di app.yaml dan nomor versi library, atau "latest" untuk versi terbaru yang tersedia di server App Engine. Modul 18 app.yaml belum memiliki salah satu bagian tersebut:

SEBELUM:

runtime: python27
threadsafe: yes
api_version: 1

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

Tambahkan bagian libraries ke app.yaml beserta entri untuk setuptools dan grpcio, dengan memilih versi terbarunya. Tambahkan juga entri placeholder runtime untuk Python 3, yang diberi komentar bersama dengan rilis 3.x saat ini, misalnya, 3.10, pada saat penulisan ini. Dengan perubahan ini, app.yaml sekarang terlihat seperti ini:

SETELAH:

#runtime: python310
runtime: python27
threadsafe: yes
api_version: 1

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

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

Python 3

Untuk pengguna Python 3 dan app.yaml, semuanya tentang menghapus item. Di bagian ini, Anda akan menghapus bagian handlers, direktif threadsafe dan api_version, serta tidak akan membuat bagian libraries.

Runtime generasi kedua tidak menyediakan library pihak ketiga bawaan, sehingga bagian libraries tidak diperlukan di app.yaml. Selain itu, penyalinan (terkadang dikenal sebagai vendoring atau self-bundling) paket pihak ketiganon-bawaan tidak lagi diperlukan. Anda hanya perlu mencantumkan library pihak ketiga yang digunakan aplikasi Anda di requirements.txt.

Bagian handlers di app.yaml adalah untuk menentukan pengendali file statis dan aplikasi (skrip). Karena runtime Python 3 mengharuskan framework web untuk melakukan peruteannya sendiri, semua pengendali skrip harus diubah menjadi auto. Jika aplikasi Anda (seperti Modul 18) tidak menayangkan file statis, semua rute akan menjadi auto, sehingga tidak relevan. Akibatnya, bagian handlers juga tidak diperlukan, jadi hapus bagian tersebut.

Terakhir, perintah threadsafe maupun api_version tidak digunakan di Python 3, jadi hapus juga perintah tersebut. Intinya, Anda harus menghapus semua bagian app.yaml sehingga hanya perintah runtime yang tersisa, yang menentukan versi Python 3 modern, misalnya, 3.10. Berikut tampilan app.yaml sebelum dan sesudah pembaruan ini:

SEBELUM:

runtime: python27
threadsafe: yes
api_version: 1

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

SETELAH:

runtime: python310

Bagi yang belum siap menghapus semuanya dari app.yaml untuk Python 3, kami telah menyediakan file alternatif app3.yaml di folder repo Modul 19. Jika Anda ingin menggunakannya untuk deployment, pastikan untuk menambahkan nama file ini di akhir perintah Anda: gcloud app deploy app3.yaml (jika tidak, file ini akan ditetapkan secara default dan men-deploy aplikasi Anda dengan file app.yaml Python 2 yang Anda biarkan tidak berubah).

appengine_config.py

Jika Anda mengupgrade ke Python 3, appengine_config.py tidak diperlukan, jadi hapus saja. Alasannya tidak diperlukan adalah karena dukungan library pihak ketiga hanya memerlukan penentuannya di requirements.txt. Pengguna Python 2, baca terus.

appengine_config.py Modul 18 memiliki kode yang sesuai untuk mendukung library pihak ketiga, misalnya, Flask dan library klien Cloud yang baru saja ditambahkan ke requirements.txt:

SEBELUM:

from google.appengine.ext import vendor

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

Namun, kode ini saja tidak cukup untuk mendukung library bawaan yang baru ditambahkan (setuptools, grpcio). Beberapa baris lagi diperlukan, jadi perbarui appengine_config.py agar terlihat seperti ini:

SETELAH:

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)

Detail selengkapnya tentang perubahan yang diperlukan untuk mendukung library klien Cloud dapat ditemukan dalam dokumentasi migrasi layanan paket.

Pembaruan konfigurasi lainnya

Jika Anda memiliki folder lib, hapus folder tersebut. Jika Anda pengguna Python 2, isi ulang folder lib dengan menjalankan perintah berikut:

pip install -t lib -r requirements.txt  # or pip2

Jika Anda telah menginstal Python 2 dan 3 di sistem pengembangan, Anda mungkin perlu menggunakan pip2, bukan pip.

6. Mengubah kode aplikasi

Bagian ini menampilkan update pada file aplikasi utama, main.py, yang menggantikan penggunaan antrean pull Task Queue App Engine dengan Cloud Pub/Sub. Tidak ada perubahan pada template web, templates/index.html. Kedua aplikasi harus beroperasi secara identik, menampilkan data yang sama.

Memperbarui impor dan inisialisasi

Ada beberapa pembaruan pada impor dan inisialisasi:

  1. Untuk impor, ganti App Engine NDB dan Task Queue dengan Cloud NDB dan Pub/Sub.
  2. Mengganti nama pullq dari nama QUEUE menjadi nama TOPIC.
  3. Dengan tugas pull, pekerja menyewanya selama satu jam, tetapi dengan Pub/Sub, waktu tunggu diukur berdasarkan per pesan, jadi hapus konstanta HOUR.
  4. Cloud API memerlukan penggunaan klien API, jadi mulai klien tersebut untuk Cloud NDB dan Cloud Pub/Sub, dengan yang terakhir menyediakan klien untuk topik dan langganan.
  5. Pub/Sub memerlukan ID project Cloud, jadi impor dan dapatkan dari google.auth.default().
  6. Pub/Sub memerlukan "nama jalur yang sepenuhnya memenuhi syarat" untuk topik dan langganan, jadi buat topik dan langganan tersebut menggunakan fungsi praktis *_path().

Di bawah ini adalah impor dan inisialisasi dari Modul 18, diikuti dengan tampilan bagian setelah menerapkan perubahan di atas, dengan sebagian besar kode baru adalah berbagai resource Pub/Sub:

SEBELUM:

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

HOUR = 3600
LIMIT = 10
TASKS = 1000
QNAME = 'pullq'
QUEUE = taskqueue.Queue(QNAME)
app = Flask(__name__)

SETELAH:

from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, pubsub

LIMIT = 10
TASKS = 1000
TOPIC = 'pullq'
SBSCR = 'worker'

app = Flask(__name__)
ds_client  = ndb.Client()
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
_, PROJECT_ID = google.auth.default()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)

Mengunjungi pembaruan model data

Model data Visit tidak berubah. Akses Datastore memerlukan penggunaan eksplisit pengelola konteks klien Cloud NDB API, ds_client.context(). Dalam kode, ini berarti Anda menggabungkan panggilan Datastore di store_visit() dan fetch_visits() dalam blok with Python. Pembaruan ini sama dengan yang dibahas dalam Modul 2.

Perubahan yang paling relevan untuk Pub/Sub adalah mengganti penambahan tugas pull Task Queue ke dalam antrean dengan memublikasikan pesan Pub/Sub ke topik pullq. Berikut adalah kode sebelum dan setelah melakukan pembaruan ini:

SEBELUM:

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 in Datastore and queue request to bump visitor count'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
    QUEUE.add(taskqueue.Task(payload=remote_addr, method='PULL'))

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

SETELAH:

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 in Datastore and queue request to bump visitor count'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
    ppc_client.publish(TOP_PATH, remote_addr.encode('utf-8'))

def fetch_visits(limit):
    'get most recent visits'
    with ds_client.context():
        return Visit.query().order(-Visit.timestamp).fetch(limit)

Update model data VisitorCount

Model data VisitorCount tidak berubah dan tidak melakukan fetch_counts() kecuali membungkus kueri Datastore-nya di dalam blok with, seperti yang diilustrasikan di bawah:

SEBELUM:

class VisitorCount(ndb.Model):
    visitor = ndb.StringProperty(repeated=False, required=True)
    counter = ndb.IntegerProperty()

def fetch_counts(limit):
    'get top visitors'
    return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)

SETELAH:

class VisitorCount(ndb.Model):
    visitor = ndb.StringProperty(repeated=False, required=True)
    counter = ndb.IntegerProperty()

def fetch_counts(limit):
    'get top visitors'
    with ds_client.context():
        return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)

Memperbarui kode pekerja

Kode pekerja diperbarui sejauh mengganti NDB dengan Cloud NDB dan Task Queue dengan Pub/Sub, tetapi alur kerjanya tetap sama.

  1. Bungkus panggilan Datastore dalam blok pengelola konteks Cloud NDB with.
  2. Pembersihan Task Queue melibatkan penghapusan semua tugas dari pull queue. Dengan Pub/Sub, "ID pengakuan" dikumpulkan di acks, lalu dihapus/dikonfirmasi di akhir.
  3. Tugas pull Task Queue disewa dengan cara yang serupa dengan pesan Pub/Sub yang ditarik. Meskipun penghapusan tugas pull dilakukan dengan objek tugas itu sendiri, pesan Pub/Sub dihapus melalui ID pengakuannya.
  4. Payload pesan Pub/Sub memerlukan byte (bukan string Python), sehingga ada encoding dan decoding UTF-8 saat memublikasikan ke dan menarik pesan dari topik.

Ganti log_visitors() dengan kode yang telah diperbarui di bawah yang menerapkan perubahan yang baru saja dijelaskan:

SEBELUM:

@app.route('/log')
def log_visitors():
    'worker processes recent visitor counts and updates them in Datastore'
    # tally recent visitor counts from queue then delete those tasks
    tallies = {}
    tasks = QUEUE.lease_tasks(HOUR, TASKS)
    for task in tasks:
        visitor = task.payload
        tallies[visitor] = tallies.get(visitor, 0) + 1
    if tasks:
        QUEUE.delete_tasks(tasks)

    # increment those counts in Datastore and return
    for visitor in tallies:
        counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
        if not counter:
            counter = VisitorCount(visitor=visitor, counter=0)
            counter.put()
        counter.counter += tallies[visitor]
        counter.put()
    return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
            len(tasks), len(tallies))

SETELAH:

@app.route('/log')
def log_visitors():
    'worker processes recent visitor counts and updates them in Datastore'
    # tally recent visitor counts from queue then delete those tasks
    tallies = {}
    acks = set()
    rsp = psc_client.pull(subscription=SUB_PATH, max_messages=TASKS)
    msgs = rsp.received_messages
    for rcvd_msg in msgs:
        acks.add(rcvd_msg.ack_id)
        visitor = rcvd_msg.message.data.decode('utf-8')
        tallies[visitor] = tallies.get(visitor, 0) + 1
    if acks:
        psc_client.acknowledge(subscription=SUB_PATH, ack_ids=acks)
    try:
        psc_client.close()
    except AttributeError:  # special handler for grpcio<1.12.0
        pass

    # increment those counts in Datastore and return
    if tallies:
        with ds_client.context():
            for visitor in tallies:
                counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
                if not counter:
                    counter = VisitorCount(visitor=visitor, counter=0)
                    counter.put()
                counter.counter += tallies[visitor]
                counter.put()
    return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
            len(msgs), len(tallies))

Tidak ada perubahan pada handler aplikasi utama root(). Tidak ada perubahan yang diperlukan dalam file template HTML, templates/index.html, sehingga semua pembaruan yang diperlukan telah selesai. Selamat telah tiba di aplikasi Modul 19 baru Anda menggunakan Cloud Pub/Sub.

7. Ringkasan/Pembersihan

Deploy aplikasi Anda untuk memverifikasi bahwa aplikasi berfungsi seperti yang diharapkan dan dalam output yang ditampilkan. Jalankan juga worker untuk memproses jumlah pengunjung. Setelah validasi aplikasi, lakukan langkah-langkah pembersihan dan pertimbangkan langkah berikutnya.

Men-deploy dan memverifikasi aplikasi

Pastikan Anda telah membuat topik pullq dan langganan worker. Jika sudah selesai dan aplikasi contoh Anda siap digunakan, deploy aplikasi Anda dengan gcloud app deploy. Outputnya akan sama dengan aplikasi Modul 18, kecuali Anda telah berhasil mengganti seluruh mekanisme antrean yang mendasarinya:

b667551dcbab1a09.png

Frontend web aplikasi kini memverifikasi bahwa bagian aplikasi ini berfungsi. Meskipun bagian aplikasi ini berhasil membuat kueri dan menampilkan pengunjung teratas dan kunjungan terbaru, ingatlah bahwa aplikasi mencatat kunjungan ini sekaligus membuat tugas penarikan untuk menambahkan pengunjung ini ke jumlah keseluruhan. Tugas tersebut kini berada dalam antrean dan menunggu untuk diproses.

Anda dapat mengeksekusinya dengan layanan backend App Engine, tugas cron, menjelajahi /log, atau mengeluarkan permintaan HTTP command line. Berikut adalah satu contoh eksekusi dan output pemanggilan kode pekerja dengan curl (ganti PROJECT_ID Anda):

$ curl https://PROJECT_ID.appspot.com/log
DONE (with 1 task[s] logging 1 visitor[s])

Jumlah yang diperbarui akan ditampilkan pada kunjungan situs berikutnya. Selesai!

Pembersihan

Umum

Jika Anda sudah selesai untuk saat ini, sebaiknya nonaktifkan aplikasi App Engine untuk menghindari penagihan. Namun, jika Anda ingin menguji atau bereksperimen lebih lanjut, platform App Engine memiliki kuota gratis, sehingga selama Anda tidak melebihi tingkat penggunaan tersebut, Anda tidak akan dikenai biaya. Biaya tersebut adalah untuk komputasi, tetapi mungkin juga ada biaya untuk layanan App Engine yang relevan, jadi periksa halaman harganya untuk mengetahui informasi selengkapnya. Jika migrasi ini melibatkan layanan Cloud lainnya, layanan tersebut akan ditagih secara terpisah. Dalam kedua kasus tersebut, jika berlaku, lihat bagian "Khusus untuk codelab ini" di bawah.

Untuk pengungkapan penuh, men-deploy ke platform komputasi serverless Google Cloud seperti App Engine akan menimbulkan biaya build dan penyimpanan kecil. Cloud Build memiliki kuota gratisnya sendiri seperti halnya Cloud Storage. Penyimpanan gambar tersebut menggunakan sebagian kuota tersebut. Namun, Anda mungkin tinggal di wilayah yang tidak memiliki paket gratis tersebut, jadi perhatikan penggunaan penyimpanan Anda untuk meminimalkan potensi biaya. "Folder" Cloud Storage tertentu yang harus Anda tinjau meliputi:

  • 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
  • Link penyimpanan di atas bergantung pada PROJECT_ID dan *LOC*Anda, misalnya, "us" jika aplikasi Anda dihosting di Amerika Serikat.

Di sisi lain, jika Anda tidak akan melanjutkan aplikasi ini atau codelab migrasi terkait lainnya dan ingin menghapus semuanya, hentikan project Anda.

Khusus untuk codelab ini

Layanan yang tercantum di bawah ini unik untuk codelab ini. Lihat dokumentasi setiap produk untuk mengetahui informasi selengkapnya:

  • Berbagai komponen Cloud Pub/Sub memiliki paket gratis; tentukan penggunaan keseluruhan Anda untuk mendapatkan gambaran yang lebih baik tentang implikasi biaya dan lihat halaman harganya untuk mengetahui detail selengkapnya.
  • Layanan App Engine Datastore disediakan oleh Cloud Datastore (Cloud Firestore dalam mode Datastore) yang juga memiliki paket gratis; lihat halaman harganya untuk mengetahui informasi selengkapnya.

Langkah berikutnya

Selain tutorial ini, modul migrasi lain yang berfokus pada cara beralih dari layanan paket lama yang perlu dipertimbangkan mencakup:

  • Modul 2: bermigrasi dari App Engine ndb ke Cloud NDB
  • Modul 7-9: melakukan migrasi dari App Engine Task Queue (tugas push) ke Cloud Tasks
  • Modul 12-13: bermigrasi dari App Engine Memcache ke Cloud Memorystore
  • Modul 15-16: bermigrasi dari Blobstore App Engine ke Cloud Storage

App Engine bukan lagi satu-satunya platform serverless di Google Cloud. Jika Anda memiliki aplikasi App Engine kecil atau aplikasi yang memiliki fungsi terbatas dan ingin mengubahnya menjadi microservice mandiri, atau Anda ingin memecah aplikasi monolitik menjadi beberapa komponen yang dapat digunakan kembali, ini adalah alasan yang baik untuk mempertimbangkan beralih ke Cloud Functions. Jika containerisasi telah menjadi bagian dari alur kerja pengembangan aplikasi Anda, terutama jika terdiri dari pipeline CI/CD (continuous integration/continuous delivery atau deployment), pertimbangkan untuk bermigrasi ke Cloud Run. Skenario ini dibahas dalam modul berikut:

  • Bermigrasi dari App Engine ke Cloud Functions: lihat Modul 11
  • Melakukan migrasi dari App Engine ke Cloud Run: lihat Modul 4 untuk mem-build aplikasi dalam container dengan Docker, atau Modul 5 untuk melakukannya tanpa container, pengetahuan Docker, atau Dockerfile

Beralih ke platform serverless lain bersifat opsional, dan sebaiknya pertimbangkan opsi terbaik untuk aplikasi dan kasus penggunaan Anda sebelum melakukan perubahan apa pun.

Terlepas dari modul migrasi mana yang akan Anda pertimbangkan berikutnya, semua konten Serverless Migration Station (codelab, video, kode sumber [jika tersedia]) dapat diakses di repo open source-nya. README repo juga memberikan panduan tentang migrasi mana yang perlu dipertimbangkan dan "urutan" Modul Migrasi yang relevan.

8. Referensi lainnya

Di bawah ini tercantum resource tambahan bagi developer yang ingin mempelajari lebih lanjut Modul Migrasi ini atau yang terkait, serta produk terkait. Hal ini mencakup tempat untuk memberikan masukan tentang konten ini, link ke kode, dan berbagai bagian dokumentasi yang mungkin berguna bagi Anda.

Masalah/masukan codelab

Jika Anda menemukan masalah dengan codelab ini, telusuri masalah Anda terlebih dahulu sebelum mengajukan masalah. Link untuk menelusuri dan membuat masalah baru:

Referensi migrasi

Link ke folder repo untuk Modul 18 (START) dan Modul 19 (FINISH) dapat ditemukan pada tabel di bawah.

Codelab

Python 2

Python 3

Modul 18

kode

(T/A)

Modul 19 (codelab ini)

kode

(sama seperti Python 2, kecuali gunakan app3.yaml, kecuali jika Anda telah mengupdate app.yaml seperti yang dibahas di atas)

Referensi online

Berikut adalah referensi yang relevan untuk tutorial ini:

Task Queue App Engine

Cloud Pub/Sub

App Engine NDB dan Cloud NDB (Datastore)

Platform App Engine

Informasi Cloud lainnya

Video

Lisensi

Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.