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

1. Ringkasan

Rangkaian codelab Stasiun Migrasi Serverless (tutorial interaktif dan mandiri) dan video terkait bertujuan untuk membantu developer tanpa server Google Cloud memodernisasi aplikasi mereka dengan memandu mereka melalui satu atau beberapa migrasi, terutama yang beralih dari layanan lama. Dengan melakukannya, aplikasi Anda akan menjadi lebih portabel serta memberi Anda lebih banyak opsi dan fleksibilitas, sehingga Anda dapat berintegrasi dengan dan mengakses lebih banyak produk Cloud serta melakukan upgrade 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 platform lainnya jika berlaku.

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

Di Modul 18, Anda akan mempelajari cara menambahkan penggunaan tugas pull di aplikasi. Dalam modul ini, Anda akan mengambil aplikasi Modul 18 yang sudah selesai dan memigrasikan penggunaan tersebut ke Cloud Pub/Sub. Tugas yang menggunakan Task Queue untuk tugas push akan dimigrasikan ke Cloud Tasks dan harus merujuk ke 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

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

Modul Migrasi 7-9 mencakup migrasi tugas push sementara Modul 18-19 berfokus pada migrasi tugas pull. Meskipun Cloud Tasks lebih cocok dengan tugas push Task Queue, Pub/Sub tidak semirip 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 mirip dengan tugas push Task Queue, sehingga push Pub/Sub tidak tercakup dalam Modul Migrasi mana pun. Codelab Modul 19 ini menunjukkan peralihan mekanisme antrean dari pull queue Task Queue ke Pub/Sub serta migrasi dari NDB App Engine ke Cloud NDB untuk akses Datastore, yang 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.

Tutorial ini menampilkan 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 kode 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 aktif dan aplikasi App Engine yang aktif. Temukan project ID Anda sesuai kebutuhan selama codelab ini, gunakan setiap kali Anda menemukan variabel PROJECT_ID.

2. Dapatkan aplikasi contoh dasar pengukuran

Salah satu prasyarat adalah aplikasi App Engine Modul 18 yang berfungsi. Jadi, selesaikan codelab-nya (direkomendasikan; link di atas) atau salin kode Modul 18 dari repo. Baik Anda menggunakan kartu milik Anda atau kami, ini adalah tempat kita akan memulai ("MULAI"). Codelab ini memandu Anda melakukan migrasi, dan mengakhirinya dengan kode yang menyerupai yang ada di folder repo Modul 19 ("FINISH").

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

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

3. Deploy (ulang) dan validasi aplikasi dasar pengukuran

Jalankan langkah-langkah berikut untuk men-deploy aplikasi Modul 18:

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

b667551dcbab1a09.png

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

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 menerapkan Cloud Pub/Sub dan Cloud Datastore (melalui library klien Cloud NDB). App Engine dan kedua Cloud API memiliki "Selalu Gratis" tingkat, dan selama tidak melebihi batas tersebut, Anda tidak akan dikenai biaya saat menyelesaikan tutorial ini. Cloud API dapat diaktifkan dari Konsol Cloud atau command line, tergantung preferensi Anda.

Dari Cloud Console

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

c7a740304e9d35b.png

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

1b6c0a2a73124f6b.jpeg

Dari command line

Meskipun menampilkan API dari konsol yang informatif secara visual, sebagian orang lebih menyukai command line. Berikan 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 untuk memberikan informasi penagihan. Jika Anda ingin mengaktifkan Cloud API lain dan ingin mengetahui URI-nya, URI tersebut dapat ditemukan di bagian bawah setiap halaman library API. Misalnya, amati pubsub.googleapis.com sebagai "Nama layanan" di bagian bawah halaman Pub/Sub tepat di atas.

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

4. Membuat resource Pub/Sub

Merangkum urutan urutan alur kerja Task Queue dari Modul 18:

  1. Modul 18 menggunakan file queue.yaml untuk membuat antrean pull bernama pullq.
  2. Aplikasi menambahkan tugas ke antrean pull untuk melacak pengunjung.
  3. Tugas akhirnya diproses oleh pekerja, disewakan selama beberapa waktu (satu jam).
  4. Tugas dijalankan untuk menghitung jumlah pengunjung terkini.
  5. Tugas akan dihapus dari antrean setelah selesai.

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

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

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

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

Meskipun produk antrean berubah, alur kerjanya tetap relatif sama:

  1. Aplikasi menggunakan topik bernama pullq, bukan antrean pull.
  2. Aplikasi mengirim pesan ke topik (pullq) alih-alih menambahkan tugas ke antrean pull.
  3. Alih-alih pekerja menyewakan tugas dari antrean pull, pelanggan yang bernama worker menarik pesan dari topik pullq.
  4. Aplikasi memproses payload pesan, sehingga meningkatkan jumlah pengunjung di Datastore.
  5. Aplikasi mengonfirmasi pesan yang diproses, bukan menghapus tugas dari antrean pull.

Dengan Task Queue, penyiapannya melibatkan pembuatan pull queue. Dengan Pub/Sub, penyiapan memerlukan pembuatan topik dan langganan. Dalam Modul 18, kami memproses queue.yaml di luar eksekusi aplikasi; kini hal yang sama juga 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 pendek)

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

Dari konsol Cloud

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

  1. Buka halaman Pub/Sub Topics di Cloud Console.
  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 adalah tampilan dialog pembuatan topik:

a05cfdbf64571ceb.png

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

  1. Buka halaman Langganan Pub/Sub di Cloud Console.
  2. Klik Buat langganan di bagian atas (lihat gambar di bawah).
  3. Masukkan worker di kolom ID Langganan.
  4. Pilih pullq dari menu pulldown Select a Cloud Pub/Sub, dengan memperhatikan "nama jalur yang sepenuhnya memenuhi syarat", misalnya, projects/PROJECT_ID/topics/pullq
  5. Untuk Delivery type, pilih Pull.
  6. Biarkan semua opsi lainnya apa adanya dan klik tombol Create.

Seperti inilah tampilan layar pembuatan langganan:

c5444375c20b0618.jpeg

Anda juga dapat membuat langganan dari halaman Topik—"pintasan" ini mungkin berguna bagi Anda dalam 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. Mengeksekusinya dengan TOPIC_ID dari 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 di dokumentasi Panduan memulai. Menggunakan command line dapat menyederhanakan alur kerja, yakni tempat topik dan langganan dibuat secara rutin, serta perintah tersebut dapat digunakan dalam skrip shell untuk tujuan ini.

Dari kode (skrip Python pendek)

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()

Eksekusi 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, dan 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 info layanan arsitektur Pub/Sub untuk mendapatkan insight tambahan.

5. Update konfigurasi

Update pada konfigurasi mencakup perubahan berbagai file konfigurasi serta pembuatan antrean pull App Engine yang setara, tetapi dalam ekosistem Cloud Pub/Sub.

Hapus queue.yaml

Kami akan beralih sepenuhnya dari Task Queue, jadi hapus queue.yaml karena Pub/Sub tidak menggunakan file ini. Daripada membuat antrean pull, Anda akan membuat topik Pub/Sub (dan langganan).

requirements.txt

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

flask
google-cloud-ndb
google-cloud-pubsub

File requirements.txt ini tidak menampilkan nomor versi apa pun, yang berarti versi terbaru akan dipilih. Jika muncul inkompatibilitas, ikuti praktik standar penggunaan nomor versi untuk mengunci versi kerja aplikasi.

app.yaml

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

Python 2

Update di atas untuk requirements.txt menambahkan penggunaan library klien Google Cloud. Ini memerlukan dukungan tambahan dari App Engine, yaitu beberapa library bawaan, setuptools dan grpcio. Penggunaan library bawaan memerlukan bagian libraries dalam app.yaml dan nomor versi library, atau "terbaru" untuk versi terbaru yang tersedia di server App Engine. app.yaml Modul 18 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 bersama dengan entri untuk setuptools dan grpcio, dengan memilih versi terbarunya. Tambahkan juga entri runtime placeholder untuk Python 3, yang dijadikan komentar bersama dengan rilis 3.x saat ini, misalnya 3.10, pada saat penulisan ini. Dengan perubahan ini, app.yaml sekarang akan 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 terkait menghapus sesuatu. Di bagian ini, Anda akan menghapus bagian handlers, perintah threadsafe dan api_version, dan Anda tidak akan membuat bagian libraries.

Runtime generasi kedua tidak menyediakan library pihak ketiga bawaan, sehingga bagian libraries tidak diperlukan di app.yaml. Selain itu, pembuatan salinan (terkadang dikenal sebagai vendor atau paket mandiri) paket pihak ketiga non bawaan tidak lagi diperlukan. Anda hanya perlu mencantumkan library pihak ketiga yang digunakan aplikasi Anda di requirements.txt.

Bagian handlers di app.yaml digunakan untuk menentukan aplikasi (skrip) dan pengendali file statis. Karena runtime Python 3 memerlukan 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, baik perintah threadsafe maupun api_version tidak digunakan di Python 3, jadi hapus perintah tersebut. Intinya adalah Anda harus menghapus semua bagian app.yaml sehingga hanya perintah runtime yang tersisa, yang menentukan versi modern Python 3, misalnya, 3.10. Berikut tampilan app.yaml sebelum dan sesudah update ini:

SEBELUM:

runtime: python27
threadsafe: yes
api_version: 1

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

SETELAH:

runtime: python310

Bagi pengguna 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 ke akhir perintah Anda: gcloud app deploy app3.yaml (jika tidak, nama file ini akan ditetapkan secara default ke dan men-deploy aplikasi Anda dengan file Python 2 app.yaml yang tidak diubah).

appengine_config.py

Jika mengupgrade ke Python 3, appengine_config.py tidak diperlukan. Jadi, hapus file tersebut. Alasan tidak diperlukan adalah dukungan library pihak ketiga hanya memerlukan penetapan 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 saja ditambahkan (setuptools, grpcio). Diperlukan beberapa baris lagi, jadi update appengine_config.py sehingga 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 lebih lanjut tentang perubahan yang diperlukan untuk mendukung library klien Cloud dapat ditemukan dalam dokumentasi memigrasikan layanan paket.

Pembaruan konfigurasi lainnya

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

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

Jika sudah menginstal Python 2 dan 3 pada sistem pengembangan, Anda mungkin harus menggunakan pip2, bukan pip.

6. Mengubah kode aplikasi

Bagian ini menampilkan update pada file aplikasi utama, main.py, menggantikan penggunaan pull queue App Engine Task Queue 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. Ganti nama pullq dari nama QUEUE menjadi nama TOPIC.
  3. Dengan tugas pull, pekerja itu menyewakannya selama satu jam, tetapi dengan Pub/Sub, waktu tunggu diukur per pesan, jadi hapus konstanta HOUR.
  4. Cloud API mengharuskan penggunaan klien API, jadi mulai klien API tersebut untuk Cloud NDB dan Cloud Pub/Sub, dan klien API tersebut akan menyediakan klien untuk topik dan langganan.
  5. Pub/Sub memerlukan project ID 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 keduanya menggunakan fungsi praktis *_path().

Berikut adalah impor dan inisialisasi dari Modul 18, diikuti dengan tampilan bagian yang seharusnya setelah penerapan perubahan di atas, dengan sebagian besar kode baru berupa 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)

Lihat 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 dalam store_visit() dan fetch_visits() di dalam blok with Python. Update ini sama dengan yang dibahas di Modul 2.

Perubahan yang paling relevan untuk Pub/Sub adalah mengganti proses antrean tugas pull Task Queue dengan publikasi pesan Pub/Sub ke topik pullq. Berikut adalah kode sebelum dan sesudah 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)

Pembaruan model data Jumlah Pengunjung

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

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)

Mengupdate kode pekerja

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

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

Ganti log_visitors() dengan kode yang diperbarui di bawah ini, 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 pengendali aplikasi utama root(). Tidak ada perubahan yang diperlukan dalam file template HTML, templates/index.html, sehingga mencakup semua pembaruan yang diperlukan. Selamat, Anda telah tiba di aplikasi Modul 19 baru menggunakan Cloud Pub/Sub.

7. Ringkasan/Pembersihan

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

Men-deploy dan memverifikasi aplikasi

Pastikan Anda sudah membuat topik pullq dan langganan worker. Jika langkah tersebut telah selesai dan aplikasi contoh Anda siap digunakan, deploy aplikasi dengan gcloud app deploy. Output harus identik dengan aplikasi Modul 18, kecuali bahwa Anda telah berhasil mengganti seluruh mekanisme antrean yang mendasarinya:

b667551dcbab1a09.png

Frontend web aplikasi kini memverifikasi bagian aplikasi ini berfungsi. Meskipun bagian aplikasi ini berhasil mengkueri dan menampilkan pengunjung teratas dan kunjungan terbaru, ingat bahwa aplikasi mencatat kunjungan ini bersama dengan membuat tugas pull untuk menambahkan pengunjung ini ke jumlah keseluruhan. Tugas tersebut sekarang ada dalam antrean yang menunggu untuk diproses.

Anda dapat menjalankan proses ini dengan layanan backend App Engine, tugas cron, menjelajahi /log, atau mengeluarkan permintaan HTTP command line. Berikut adalah satu contoh eksekusi dan cara memanggil 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 kemudian akan terlihat pada kunjungan situs web berikutnya. Selesai.

Pembersihan

Umum

Jika sudah selesai untuk saat ini, sebaiknya nonaktifkan aplikasi App Engine agar tidak menimbulkan penagihan. Namun, jika Anda ingin menguji atau bereksperimen lagi, platform App Engine memiliki kuota gratis, dan asalkan Anda tidak melebihi tingkat penggunaan tersebut, Anda tidak akan dikenai biaya. Itu berlaku 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 "Khusus untuk codelab ini" di bawah ini.

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

  • 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*asi Anda, misalnya, "us" jika aplikasi Anda dihosting di AS.

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

Khusus untuk codelab ini

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

  • Komponen Cloud Pub/Sub yang berbeda memiliki paket gratis; menentukan 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 untuk beralih dari layanan paket lama yang perlu dipertimbangkan meliputi:

  • Modul 2: bermigrasi dari App Engine ndb ke Cloud NDB
  • Modul 7-9: bermigrasi dari Task Queue App Engine (tugas push) ke Cloud Tasks
  • Modul 12-13: bermigrasi dari Memcache App Engine 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, berikut adalah alasan bagus untuk mempertimbangkan beralih ke Cloud Functions. Jika containerization telah menjadi bagian dari alur kerja pengembangan aplikasi Anda, terutama jika terdiri dari pipeline CI/CD (continuous integration/continuous delivery atau deployment), sebaiknya lakukan migrasi ke Cloud Run. Skenario ini dibahas dalam modul berikut:

  • Bermigrasi dari App Engine ke Cloud Functions: lihat Modul 11
  • Bermigrasi dari App Engine ke Cloud Run: lihat Modul 4 untuk menyimpan aplikasi Anda ke dalam container dengan Docker, atau Modul 5 untuk melakukannya tanpa container, pengetahuan Docker, atau Dockerfile

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

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

8. Referensi lainnya

Di bawah ini adalah referensi tambahan untuk developer yang mempelajari lebih lanjut Modul Migrasi ini atau terkait serta produk terkait. Ini mencakup tempat untuk memberikan masukan tentang konten ini, link ke kode, dan berbagai 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 menggunakan app3.yaml kecuali Anda mengupdate app.yaml seperti yang dibahas di atas)

Referensi {i>online<i}

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.