App Engine Görev Sırası pull görevlerini Cloud Pub/Sub'a taşıma (Modül 19)

1. Genel Bakış

Serverless Migration Station serisi codelab'ler (kendi hızınızda ilerleyebileceğiniz, uygulamalı eğitimler) ve ilgili videolar, Google Cloud sunucusuz geliştiricilerin öncelikle eski hizmetlerden uzaklaşarak bir veya daha fazla taşıma işlemi yapmalarına rehberlik ederek uygulamalarını modernleştirmelerine yardımcı olmayı amaçlar. Bu sayede uygulamalarınız daha taşınabilir hale gelir, daha fazla seçenek ve esneklik elde edersiniz. Böylece daha geniş bir Cloud ürün yelpazesiyle entegrasyon yapabilir, bu ürünlere erişebilir ve yeni dil sürümlerine daha kolay yükseltebilirsiniz. Başlangıçta öncelikle App Engine (standart ortam) geliştiricileri olmak üzere en eski Cloud kullanıcılarına odaklanılsa da bu seri, Cloud Functions ve Cloud Run gibi diğer sunucusuz platformları veya uygun olduğu durumlarda başka platformları da kapsayacak kadar geniştir.

Bu codelab'in amacı, Python 2 App Engine geliştiricilerine App Engine görev sırası çekme görevlerinden Cloud Pub/Sub'a nasıl geçiş yapacaklarını göstermektir. Ayrıca, Datastore erişimi için App Engine NDB'den Cloud NDB'ye örtülü bir taşıma (öncelikle 2. modülde ele alınır) ve Python 3'e yükseltme de vardır.

18. modülde, uygulamanıza çekme görevlerinin kullanımını nasıl ekleyeceğinizi öğrenirsiniz. Bu modülde ise tamamlanmış 18. modül uygulamasını alıp bu kullanımı Cloud Pub/Sub'a taşıyacaksınız. Push görevleri için Görev Sıraları'nı kullananlar bunun yerine Cloud Tasks'e geçiş yapacak ve 7-9. modüllere başvuracaktır.

Bu demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:

İhtiyacınız olanlar

Anket

Bu eğitimi nasıl kullanacaksınız?

Yalnızca okuyun Okuyun ve alıştırmaları tamamlayın

Python ile ilgili deneyiminizi nasıl değerlendirirsiniz?

Yeni başlayan Orta düzey Uzman

Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?

Başlangıç Orta İleri

2. Arka plan

App Engine görev sırası hem push hem de çekme görevlerini destekler. Google Cloud, uygulama taşınabilirliğini iyileştirmek için Task Queue gibi eski paketlenmiş hizmetlerden diğer Cloud bağımsız veya üçüncü taraf eşdeğer hizmetlerine geçiş yapmanızı önerir.

7-9. taşıma modüllerinde push görev taşıma, 18-19. modüllerde ise pull görev taşıma ele alınmaktadır. Cloud Tasks, Task Queue push görevleriyle daha yakından eşleşse de Pub/Sub, Task Queue pull görevleriyle o kadar yakın bir analog değildir.

Pub/Sub, Görev Sırası'nın sağladığı çekme işlevinden daha fazla özelliğe sahiptir. Örneğin, Pub/Sub'da push işlevi de vardır ancak Cloud Tasks, Görev Sırası push görevlerine daha çok benzer. Bu nedenle, Pub/Sub push, taşıma modüllerinin hiçbirinde yer almaz. Bu 19. modül codelab'inde, sıralama mekanizmasının görev sırası çekme sıralarından Pub/Sub'a geçirilmesi ve Datastore erişimi için App Engine NDB'den Cloud NDB'ye geçiş (2. Modül'deki geçişin tekrarı) gösterilmektedir.

18. Modül kodu, Python 2 örnek uygulaması olarak "tanıtılsa" da kaynağın kendisi Python 2 ve 3 ile uyumludur ve 19. Modül'de Cloud Pub/Sub'a (ve Cloud NDB'ye) geçiş yapıldıktan sonra da bu şekilde kalır.

Bu eğitimde aşağıdaki adımlar yer almaktadır:

  1. Kurulum/Ön Hazırlık
  2. Yapılandırmayı güncelleyin
  3. Uygulama kodunu değiştirme

3. Kurulum/Ön Hazırlık

Bu bölümde aşağıdakilerin nasıl yapılacağı açıklanmaktadır:

  1. Cloud projenizi ayarlama
  2. Temel örnek uygulamayı edinme
  3. Temel uygulamayı (yeniden) dağıtma ve doğrulama
  4. Yeni Google Cloud hizmetlerini/API'lerini etkinleştirme

Bu adımlar, çalışan bir kodla başlamanızı ve kodun Cloud hizmetlerine taşınmaya hazır olmasını sağlar.

1. Proje oluşturma

18. modül codelab'ini tamamladıysanız aynı projeyi (ve kodu) yeniden kullanın. Alternatif olarak, yepyeni bir proje oluşturun veya mevcut başka bir projeyi yeniden kullanın. Projenin etkin bir faturalandırma hesabına ve etkin bir App Engine uygulamasına sahip olduğundan emin olun. Bu codelab sırasında ihtiyacınız olacağı için proje kimliğinizi bulun. PROJECT_ID değişkeniyle karşılaştığınızda proje kimliğinizi kullanın.

2. Temel örnek uygulamayı edinme

Ön koşullardan biri, çalışan bir 18. Modül App Engine uygulamasıdır. Bu nedenle, codelab'ini tamamlayın (önerilir; yukarıdaki bağlantı) veya depodan 18. Modül kodunu kopyalayın. İster kendi verilerinizi ister bizim verilerimizi kullanın, işe buradan başlayacağız ("BAŞLANGIÇ"). Bu codelab'de, 19. modülün depo klasöründeki ("FINISH") koda benzer bir kodla sonuçlanan taşıma işlemi adım adım açıklanmaktadır.

Hangi 18. Modül uygulamasını kullandığınızdan bağımsız olarak klasör aşağıdaki gibi görünmelidir. Klasörde lib klasörü de olabilir:

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

3. Temel uygulamayı (yeniden) dağıtma ve doğrulama

18. Modül uygulamasını dağıtmak için aşağıdaki adımları uygulayın:

  1. Varsa lib klasörünü silin ve lib öğesini yeniden doldurmak için pip install -t lib -r requirements.txt komutunu çalıştırın. Geliştirme makinenizde hem Python 2 hem de 3 yüklüyse pip2 kullanmanız gerekebilir.
  2. gcloud komut satırı aracını yüklediğinizden ve başlattığınızdan emin olun ve kullanımını inceleyin.
  3. (İsteğe bağlı) Her gcloud komutunu verdiğinizde PROJECT_ID değerini girmek istemiyorsanız Cloud projenizi gcloud config set project PROJECT_ID ile ayarlayın.
  4. Örnek uygulamayı gcloud app deploy ile dağıtma
  5. Uygulamanın sorunsuz ve beklendiği gibi çalıştığını doğrulayın. 18. Modül'deki codelab'i tamamladıysanız uygulamada en son ziyaretlerle birlikte en çok ziyaret eden kullanıcılar gösterilir (aşağıda gösterilmiştir). Aksi takdirde, gösterilecek ziyaretçi sayısı olmayabilir.

b667551dcbab1a09.png

18. Modül örnek uygulamasını taşımadan önce, değiştirilen uygulamanın kullanacağı Cloud hizmetlerini etkinleştirmeniz gerekir.

4. Yeni Google Cloud hizmetlerini/API'lerini etkinleştirme

Eski uygulama, ek kurulum gerektirmeyen App Engine paketlenmiş hizmetlerini kullanıyordu ancak bağımsız Cloud hizmetleri ek kurulum gerektiriyor. Güncellenen uygulama ise hem Cloud Pub/Sub hem de Cloud Datastore'u (Cloud NDB istemci kitaplığı aracılığıyla) kullanacak. App Engine ve her iki Cloud API'sinde de "Always Free" katmanı kotaları vardır. Bu sınırlarda kaldığınız sürece bu eğitimi tamamlarken herhangi bir ücret ödemezsiniz. Cloud API'leri, tercihinize bağlı olarak Cloud Console'dan veya komut satırından etkinleştirilebilir.

Cloud Console'dan

Cloud Console'da API Yöneticisi Kitaplığı sayfasına (doğru proje için) gidin ve sayfanın ortasındaki arama çubuğunu kullanarak Cloud Datastore ve Cloud Pub/Sub API'lerini arayın:

c7a740304e9d35b.png

Her API için Etkinleştir düğmesini ayrı ayrı tıklayın. Fatura bilgileri istenebilir. Örneğin, Cloud Pub/Sub API Kitaplığı sayfası şöyledir:

1b6c0a2a73124f6b.jpeg

Komut satırından

Konsoldan API'leri etkinleştirmek görsel olarak bilgilendirici olsa da bazı kullanıcılar komut satırını tercih eder. Her iki API'yi de aynı anda etkinleştirmek için gcloud services enable pubsub.googleapis.com datastore.googleapis.com komutunu verin:

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

Fatura bilgileri istenebilir. Diğer Cloud API'lerini etkinleştirmek ve URI'lerini öğrenmek istiyorsanız bu URI'leri her API'nin kitaplık sayfasının en altında bulabilirsiniz. Örneğin, hemen yukarıdaki Pub/Sub sayfasının en alt kısmında "Hizmet adı" olarak pubsub.googleapis.com ifadesini görebilirsiniz.

Adımlar tamamlandıktan sonra projeniz API'lere erişebilir. Şimdi uygulamayı bu API'leri kullanacak şekilde güncelleme zamanı.

4. Pub/Sub kaynakları oluşturma

18. modüldeki Görev Kuyruğu iş akışının sıra düzenini özetleyelim:

  1. 18. modülde, queue.yaml adlı bir çekme sırası oluşturmak için pullq dosyası kullanıldı.
  2. Uygulama, ziyaretçileri izlemek için çekme sırasına görevler ekler.
  3. Görevler, sınırlı bir süre (bir saat) için kiralanan bir çalışan tarafından işlenir.
  4. Görevler, son ziyaretçi sayılarını hesaplamak için yürütülür.
  5. Görevler tamamlandığında sıradan silinir.

Pub/Sub ile benzer bir iş akışını kopyalayacaksınız. Bir sonraki bölümde, gerekli Pub/Sub kaynaklarını oluşturmanın üç farklı yoluyla birlikte temel Pub/Sub terminolojisi tanıtılmaktadır.

App Engine görev sırası (çekme) ve Cloud Pub/Sub terminolojisi

Pub/Sub'a geçmek için kelime dağarcığınızda küçük bir düzenleme yapmanız gerekir. Aşağıda, her iki üründeki alakalı terimlerle birlikte birincil kategoriler listelenmiştir. Benzer karşılaştırmaların yer aldığı taşıma kılavuzunu da inceleyin.

  • Veri yapısını sıraya alma: Task Queue ile veriler çekme kuyruklarına, Pub/Sub ile veriler konulara gider.
  • Sıraya alınmış veri birimleri: Görev Sırası ile çekme görevleri, Pub/Sub ile mesaj olarak adlandırılır.
  • Veri işleyenler: Task Queue ile çalışanlar çekme görevlerine erişir. Pub/Sub ile mesaj almak için abonelikler/aboneler gerekir.
  • Veri ayıklama: Bir çekme görevini kiralama, bir konudan (abonelik aracılığıyla) mesaj çekmeyle aynıdır.
  • Temizleme/tamamlama: İşiniz bittiğinde bir görev sırası görevini çekme sırasından silmek, bir Pub/Sub mesajını onaylamaya benzer.

Sıraya alma ürünü değişse de iş akışı büyük ölçüde aynı kalır:

  1. Uygulama, çekme sırası yerine pullq adlı bir konu kullanır.
  2. Uygulama, görevleri çekme sırasına eklemek yerine bir konuya mesaj gönderir (pullq).
  3. Çalışan, çekme sırasından görevleri kiralamak yerine worker adlı bir abone, pullq konusundan mesajları çeker.
  4. Uygulama, ileti yüklerini işleyerek Datastore'daki ziyaretçi sayılarını artırır.
  5. Uygulama, görevleri çekme sırasından silmek yerine işlenen mesajları onaylar.

Görev Sırası ile kurulum, pull sırası oluşturmayı içerir. Pub/Sub ile kurulum için hem konu hem de abonelik oluşturulması gerekir. 18. modülde, queue.yaml uygulama yürütme dışında işleniyordu. Şimdi aynı işlemin Pub/Sub ile yapılması gerekiyor.

Konu ve abonelik oluşturmak için üç seçenek vardır:

  1. Cloud Console'dan
  2. Komut satırından veya
  3. Koddan (kısa Python komut dosyası)

Aşağıdaki seçeneklerden birini belirleyin ve Pub/Sub kaynaklarınızı oluşturmak için ilgili talimatları uygulayın.

Cloud Console'dan

Cloud Console'dan konu oluşturmak için aşağıdaki adımları uygulayın:

  1. Cloud Console Pub/Sub Konuları sayfasına gidin.
  2. Üst kısımdaki Konu oluştur'u tıklayın. Yeni bir iletişim kutusu açılır (aşağıdaki resme bakın).
  3. Konu kimliği alanına pullq girin.
  4. İşaretli tüm seçeneklerin işaretini kaldırın ve Google tarafından yönetilen şifreleme anahtarı'nı seçin.
  5. Oluştur konu düğmesini tıklayın.

Konu oluşturma iletişim kutusu şu şekilde görünür:

a05cfdbf64571ceb.png

Artık bir konunuz olduğuna göre bu konu için bir abonelik oluşturulması gerekir:

  1. Cloud Console'da Pub/Sub Abonelikleri sayfasına gidin.
  2. En üstteki Abonelik oluştur'u tıklayın (aşağıdaki resme bakın).
  3. Abonelik Kimliği alanına worker girin.
  4. Cloud Pub/Sub konusu seçin açılır listesinden pullq öğesini seçin. "Tam nitelikli yol adını" (ör. projects/PROJECT_ID/topics/pullq) not edin.
  5. Teslim türü için Çekme'yi seçin.
  6. Diğer tüm seçenekleri olduğu gibi bırakıp Oluştur düğmesini tıklayın.

Abonelik oluşturma ekranı aşağıdaki gibi görünür:

c5444375c20b0618.jpeg

Ayrıca Konular sayfasından da abonelik oluşturabilirsiniz. Bu "kısayol", konuları aboneliklerle ilişkilendirmenize yardımcı olabilir. Abonelik oluşturma hakkında daha fazla bilgi edinmek için belgelere göz atın.

Komut satırından

Pub/Sub kullanıcıları sırasıyla gcloud pubsub topics create TOPIC_ID ve gcloud pubsub subscriptions create SUBSCRIPTION_ID --topic=TOPIC_ID komutlarıyla konular ve abonelikler oluşturabilir. Bunları pullq TOPIC_ID ve worker SUBSCRIPTION_ID ile yürütmek, PROJECT_ID projesi için aşağıdaki çıktıyı verir:

$ 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].

Hızlı başlangıç belgelerindeki bu sayfayı da inceleyin. Komut satırını kullanmak, konuların ve aboneliklerin düzenli olarak oluşturulduğu iş akışlarını basitleştirebilir. Bu amaçla, kabuk komut dosyalarında bu tür komutlar kullanılabilir.

Koddan (kısa Python komut dosyası)

Konu ve abonelik oluşturmayı otomatikleştirmenin bir diğer yolu da kaynak kodda Pub/Sub API'yi kullanmaktır. Aşağıda, 19. Modül depo klasöründeki maker.py komut dosyasının kodu verilmiştir.

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

Bu komut dosyasının yürütülmesi, hata olmaması durumunda beklenen çıkışı verir:

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

API'yi çağırarak önceden var olan kaynakları oluşturmak, istemci kitaplığı tarafından oluşturulan ve komut dosyası tarafından sorunsuz bir şekilde işlenen bir google.api_core.exceptions.AlreadyExists istisnasına neden olur:

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

Pub/Sub'ı yeni kullanmaya başladıysanız ek bilgiler için Pub/Sub mimarisi tanıtım yazısına bakın.

5. Yapılandırmayı güncelleyin

Yapılandırmadaki güncellemeler, hem çeşitli yapılandırma dosyalarını değiştirmeyi hem de App Engine çekme kuyruklarının eşdeğerini Cloud Pub/Sub ekosisteminde oluşturmayı içerir.

queue.yaml dosyasını silin.

Task Queue'dan tamamen uzaklaşıyoruz. Bu nedenle, Pub/Sub bu dosyayı kullanmadığından queue.yaml dosyasını silin. Çekme sırası oluşturmak yerine Pub/Sub konusu (ve abonelik) oluşturursunuz.

requirements.txt

18. modüldeki flask'e katılmak için hem google-cloud-ndb hem de google-cloud-pubsub'yi requirements.txt'ye ekleyin. Güncellenen 19. modülünüz requirements.txt artık aşağıdaki gibi görünmelidir:

flask
google-cloud-ndb
google-cloud-pubsub

Bu requirements.txt dosyasında sürüm numaraları yer almaz. Bu nedenle, en son sürümler seçilir. Uyumsuzluklar ortaya çıkarsa bir uygulamanın çalışan sürümlerini kilitlemek için sürüm numaralarını kullanma standart uygulamasını izleyin.

app.yaml

app.yaml ile ilgili değişiklikler, Python 2'yi kullanmaya devam etmenize veya Python 3'e yükseltmenize bağlı olarak farklılık gösterir.

Python 2

requirements.txt ile ilgili yukarıdaki güncelleme, Google Cloud istemci kitaplıklarının kullanımını ekler. Bunlar için App Engine'den ek destek gerekir. Bu destek, setuptools ve grpcio olmak üzere iki yerleşik kitaplık şeklinde sağlanır. Yerleşik kitaplıkların kullanılması için app.yaml içinde libraries bölümü ve kitaplık sürüm numaraları ya da App Engine sunucularında kullanılabilen en son sürüm için "latest" ifadesi gerekir. 18. Modül app.yaml henüz bu bölümlerden birine sahip değil:

ÖNCESİ:

runtime: python27
threadsafe: yes
api_version: 1

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

libraries bölümüne app.yaml ekleyin. Hem setuptools hem de grpcio için girişler ekleyip en son sürümlerini seçin. Ayrıca, bu yazı yazıldığı sırada geçerli olan 3.x sürümüyle (ör. 3.10) birlikte yorumlanmış bir Python 3 için yer tutucu runtime girişi de ekleyin. Bu değişikliklerle birlikte app.yaml artık şu şekilde görünüyor:

SONRASI:

#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

Python 3 kullanıcıları ve app.yaml için her şey kaldırma işleminden ibarettir. Bu bölümde handlers bölümünü, threadsafe ve api_version yönergelerini sileceksiniz ve libraries bölümü oluşturmayacaksınız.

İkinci nesil çalışma zamanları yerleşik üçüncü taraf kitaplıklar sağlamadığından libraries bölümü app.yaml içinde gerekli değildir. Ayrıca, yerleşik olmayan üçüncü taraf paketlerinin kopyalanması (bazen satma veya kendi kendine paketleme olarak da bilinir)artık gerekli değildir. Uygulamanızın kullandığı üçüncü taraf kitaplıklarını yalnızca requirements.txt bölümünde listelemeniz gerekir.

app.yaml içindeki handlers bölümü, uygulama (komut dosyası) ve statik dosya işleyicilerini belirtmek için kullanılır. Python 3 çalışma zamanı, web çerçevelerinin kendi yönlendirmelerini gerçekleştirmesini gerektirdiğinden tüm komut dosyası işleyicileri auto olarak değiştirilmelidir. Uygulamanız (ör. 18. Modül) statik dosyalar sunmuyorsa tüm rotalar auto olur ve bu da rotaları alakasız hale getirir. Bu nedenle, handlers bölümüne de gerek kalmaz. Bu bölümü de silin.

Son olarak, Python 3'te threadsafe ve api_version yönergeleri kullanılmadığından bunları da silin. Sonuç olarak, app.yaml'nın tüm bölümlerini silerek yalnızca runtime yönergesinin kalmasını sağlamalısınız. Bu yönerge, Python 3'ün modern bir sürümünü (ör. 3.10) belirtir. app.yaml, bu güncellemelerden önce ve sonra aşağıdaki gibi görünür:

ÖNCESİ:

runtime: python27
threadsafe: yes
api_version: 1

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

SONRASI:

runtime: python310

Python 3 için app.yaml'dan her şeyi silmeye hazır olmayanlar için 19. modülün depo klasöründe app3.yaml alternatif bir dosya sağladık. Bunun yerine dağıtımlar için kullanmak istiyorsanız bu dosya adını komutunuzun sonuna eklediğinizden emin olun: gcloud app deploy app3.yaml (Aksi takdirde, varsayılan olarak Python 2 app.yaml dosyası kullanılır ve uygulamanız bu dosya ile dağıtılır).

appengine_config.py

Python 3'e yükseltiyorsanız appengine_config.py gerekmez. Bu nedenle, appengine_config.py'yı silin. Üçüncü taraf kitaplık desteği için yalnızca requirements.txt içinde belirtilmesi gerektiğinden bu kitaplıkların eklenmesi gerekli değildir. Python 2 kullanıcıları, okumaya devam edin.

18. Modül appengine_config.py, üçüncü taraf kitaplıklarını desteklemek için uygun kodu içerir. Örneğin, Flask ve requirements.txt'e yeni eklenen Cloud istemci kitaplıkları:

ÖNCESİ:

from google.appengine.ext import vendor

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

Ancak bu kod, yeni eklenen yerleşik kitaplıkları (setuptools, grpcio) desteklemek için yeterli değildir. Birkaç satır daha eklenmesi gerekir. Bu nedenle, appengine_config.py dosyasını aşağıdaki gibi görünecek şekilde güncelleyin:

SONRASI:

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)

Cloud istemci kitaplıklarını desteklemek için gereken değişikliklerle ilgili daha fazla bilgiyi paketlenmiş hizmetleri taşıma belgelerinde bulabilirsiniz.

Diğer yapılandırma güncellemeleri

lib klasörünüz varsa silin. Python 2 kullanıcısıysanız aşağıdaki komutu vererek lib klasörünü yeniden doldurun:

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

Geliştirme sisteminizde hem Python 2 hem de 3 yüklüyse pip yerine pip2 kullanmanız gerekebilir.

6. Uygulama kodunu değiştirme

Bu bölümde, App Engine görev sırası çekme sıralarının Cloud Pub/Sub ile değiştirilmesiyle ilgili olarak ana uygulama dosyası main.py'daki güncellemeler yer almaktadır. Web şablonunda herhangi bir değişiklik yapılmadı, templates/index.html. Her iki uygulama da aynı şekilde çalışmalı ve aynı verileri göstermelidir.

İçe aktarma işlemlerini ve başlatmayı güncelleme

İçe aktarma ve başlatma ile ilgili çeşitli güncellemeler yapıldı:

  1. İçe aktarmalar için App Engine NDB ve Görev Sırası'nı Cloud NDB ve Pub/Sub ile değiştirin.
  2. pullq olan adı QUEUE adından TOPIC adına değiştirin.
  3. Çekme görevlerinde çalışan, görevleri bir saatliğine kiralıyordu ancak Pub/Sub'da zaman aşımları mesaj bazında ölçülür. Bu nedenle HOUR sabitini silin.
  4. Cloud API'leri bir API istemcisinin kullanılmasını gerektirir. Bu nedenle, Cloud NDB ve Cloud Pub/Sub için API istemcilerini başlatın. Cloud Pub/Sub, hem konular hem de abonelikler için istemciler sağlar.
  5. Pub/Sub için Cloud projesi kimliği gerekir. Bu nedenle, google.auth.default() adresinden içe aktarın ve alın.
  6. Pub/Sub, konular ve abonelikler için "tam nitelikli yol adları" gerektirir. Bu nedenle, bunları *_path() kolaylık işlevlerini kullanarak oluşturun.

Aşağıda, 18. modüldeki içe aktarmalar ve başlatma işlemleri ile yukarıdaki değişiklikler uygulandıktan sonra bölümlerin nasıl görüneceği gösterilmektedir. Yeni kodun çoğu çeşitli Pub/Sub kaynaklarından oluşmaktadır:

ÖNCESİ:

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

SONRASI:

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)

Veri modeli güncellemeleri sayfasını ziyaret edin.

Visit veri modeli değişmez. Datastore erişimi için Cloud NDB API istemci bağlam yöneticisinin (ds_client.context()) açıkça kullanılması gerekir. Kodda bu, Datastore çağrılarını Python with bloklarında hem store_visit() hem de fetch_visits() ile sarmalamanız gerektiği anlamına gelir. Bu güncelleme, 2. modülde ele alınanlarla aynıdır.

Pub/Sub için en alakalı değişiklik, bir görev sırası çekme görevinin sıraya alınmasını pullq konusuna bir Pub/Sub mesajı yayınlamakla değiştirmektir. Aşağıda, bu güncellemeler yapılmadan önceki ve sonraki kod verilmiştir:

ÖNCESİ:

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)

SONRASI:

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)

VisitorCount veri modeli güncellemeleri

VisitorCount veri modeli değişmez ve aşağıda gösterildiği gibi Datastore sorgusunu with bloğunun içine sarmak dışında fetch_counts().

ÖNCESİ:

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)

SONRASI:

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)

Çalışan kodunu güncelleme

NDB'nin Cloud NDB ile, Task Queue'nun ise Pub/Sub ile değiştirilmesi dışında çalışan kodu güncellenmez. İş akışı ise aynı kalır.

  1. Datastore çağrılarını Cloud NDB bağlam yöneticisi with bloğuna sarmalayın.
  2. Görev sırası temizleme, çekme sırasındaki tüm görevlerin silinmesini içerir. Pub/Sub ile "onay kimlikleri" acks içinde toplanır ve sonunda silinir/onaylanır.
  3. Görev sırası çekme görevleri, Pub/Sub mesajlarının çekilmesine benzer şekilde kiralanır. Çekme görevleri, görev nesneleriyle birlikte silinirken Pub/Sub mesajları onay kimlikleriyle silinir.
  4. Pub/Sub mesaj yükleri için bayt (Python dizeleri değil) gerekir. Bu nedenle, bir konuda yayın yaparken ve bir konudan mesaj çekerken sırasıyla UTF-8 kodlama ve kod çözme işlemleri yapılır.

log_visitors() yerine, az önce açıklanan değişiklikleri uygulayan aşağıdaki güncellenmiş kodu kullanın:

ÖNCESİ:

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

SONRASI:

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

Ana uygulama işleyicisinde root() herhangi bir değişiklik yapılmamıştır. HTML şablon dosyasında (templates/index.html) da değişiklik yapılması gerekmez. Bu nedenle, gerekli tüm güncellemeler bu dosyada yer alır. Cloud Pub/Sub'ı kullanarak yeni Modül 19 uygulamanıza ulaştığınız için tebrik ederiz.

7. Özet/Temizleme

Uygulamanızı, amaçlandığı şekilde ve yansıtılan tüm çıktılarda çalıştığını doğrulamak için dağıtın. Ayrıca, ziyaretçi sayılarını işlemek için çalışanı da çalıştırın. Uygulama doğrulandıktan sonra temizleme adımlarını uygulayın ve sonraki adımları göz önünde bulundurun.

Uygulamayı dağıtma ve doğrulama

pullq konusunu ve worker aboneliğini daha önce oluşturduğunuzdan emin olun. Bu işlem tamamlandıysa ve örnek uygulamanız kullanıma hazırsa uygulamanızı gcloud app deploy ile dağıtın. Çıkış, temeldeki tüm kuyruk mekanizmasını başarıyla değiştirmeniz dışında 18. Modül uygulamasının aynısı olmalıdır:

b667551dcbab1a09.png

Uygulamanın web ön ucu artık uygulamanın bu bölümünün çalıştığını doğruluyor. Uygulamanın bu bölümü, en iyi ziyaretçileri ve en son ziyaretleri başarıyla sorgulayıp gösterse de uygulamanın, bu ziyaretçiyi genel sayıya eklemek için bir çekme görevi oluşturmanın yanı sıra bu ziyareti de kaydettiğini unutmayın. Bu görev şu anda işlenmeyi beklemek üzere sıraya alındı.

Bu işlemi App Engine arka uç hizmeti, cron işi, /log adresine göz atma veya komut satırı HTTP isteği gönderme ile gerçekleştirebilirsiniz. curl ile çalışan kodunu çağırmanın bir örnek yürütme ve çıkışını burada bulabilirsiniz (PROJECT_ID yerine kendi değerinizi girin):

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

Güncellenen sayı, bir sonraki web sitesi ziyaretinde gösterilir. İşte bu kadar.

Temizleme

Genel

Şimdilik işiniz bittiyse faturalandırmayı önlemek için App Engine uygulamanızı devre dışı bırakmanızı öneririz. Ancak biraz daha test veya deneme yapmak isterseniz App Engine platformunda ücretsiz kota bulunur. Bu nedenle, kullanım katmanını aşmadığınız sürece sizden ücret alınmaz. Bu, işlem için geçerlidir ancak ilgili App Engine hizmetleri için de ücret alınabilir. Daha fazla bilgi için fiyatlandırma sayfasını inceleyin. Bu taşıma işlemine başka Cloud hizmetleri de dahilse bunlar ayrı olarak faturalandırılır. Her iki durumda da varsa aşağıdaki "Bu codelab'e özel" bölümüne bakın.

Tam açıklama yapmak gerekirse App Engine gibi bir Google Cloud sunucusuz bilgi işlem platformuna dağıtım yapıldığında küçük derleme ve depolama maliyetleri oluşur. Cloud Build ve Cloud Storage'ın kendi ücretsiz kotaları vardır. Bu görüntünün depolanması, kotanın bir kısmını kullanır. Ancak, böyle bir ücretsiz katmanın olmadığı bir bölgede yaşıyor olabilirsiniz. Bu nedenle, olası maliyetleri en aza indirmek için depolama alanı kullanımınıza dikkat edin. İncelemeniz gereken belirli Cloud Storage "klasörleri" şunlardır:

  • 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
  • Yukarıdaki depolama bağlantıları, PROJECT_ID ve *LOC*ınıza bağlıdır. Örneğin, uygulamanız ABD'de barındırılıyorsa "us" olur.

Öte yandan, bu uygulamaya veya ilgili diğer taşıma codelab'lerine devam etmeyecekseniz ve her şeyi tamamen silmek istiyorsanız projenizi kapatın.

Bu codelab'e özel

Aşağıda listelenen hizmetler bu codelab'e özeldir. Daha fazla bilgi için her ürünün belgelerine bakın:

Sonraki adımlar

Bu eğitimin yanı sıra eski paketlenmiş hizmetlerden geçişe odaklanan diğer taşıma modüllerini de inceleyebilirsiniz:

  • 2. Modül: App Engine ndb'den Cloud NDB'ye taşıma
  • 7-9. modüller: App Engine görev sırasından (push görevleri) Cloud Tasks'e geçiş
  • 12-13. modüller: App Engine Memcache'ten Cloud Memorystore'a geçiş
  • 15-16. Modüller: App Engine Blobstore'dan Cloud Storage'a geçiş

App Engine artık Google Cloud'daki tek sunucusuz platform değil. Küçük bir App Engine uygulamanız veya sınırlı işlevselliğe sahip bir uygulamanız varsa ve bunu bağımsız bir mikro hizmete dönüştürmek istiyorsanız ya da tek bir uygulamayı birden fazla yeniden kullanılabilir bileşene ayırmak istiyorsanız Cloud Functions'a geçmeyi düşünebilirsiniz. Container mimarisine alma, özellikle CI/CD (sürekli entegrasyon/sürekli teslim veya dağıtım) ardışık düzeninden oluşuyorsa uygulama geliştirme iş akışınızın bir parçası haline geldiyse Cloud Run'a geçmeyi düşünebilirsiniz. Bu senaryolar aşağıdaki modüllerde ele alınır:

  • App Engine'den Cloud Functions'a geçiş: 11. Modül'e bakın.
  • App Engine'den Cloud Run'a taşıma: Uygulamanızı Docker ile container mimarisine almak için 4. Modül'e, container'lar, Docker bilgisi veya Dockerfile olmadan yapmak için 5. Modül'e bakın.

Başka bir sunucusuz platforma geçmek isteğe bağlıdır. Herhangi bir değişiklik yapmadan önce uygulamalarınız ve kullanım alanlarınız için en iyi seçenekleri göz önünde bulundurmanızı öneririz.

Bir sonraki geçiş modülünüz hangisi olursa olsun, tüm Serverless Migration Station içeriklerine (codelab'ler, videolar, kaynak kodu [varsa]) açık kaynaklı depodan erişebilirsiniz. Depodaki README, hangi taşımaların dikkate alınması gerektiği ve ilgili "sıra" hakkında da rehberlik sağlar.

8. Ek kaynaklar

Bu veya ilgili geçiş modülünü ve ilgili ürünleri daha ayrıntılı incelemek isteyen geliştiriciler için ek kaynaklar aşağıda listelenmiştir. Bu sayfada, içerikle ilgili geri bildirimde bulunabileceğiniz yerler, kod bağlantıları ve faydalı bulabileceğiniz çeşitli belgeler yer alır.

Codelab'lerle ilgili sorunlar/geri bildirimler

Bu codelab ile ilgili sorun bulursanız lütfen göndermeden önce sorununuzu arayın. Arama yapma ve yeni sorunlar oluşturma bağlantıları:

Taşıma kaynakları

18. Modül (BAŞLANGIÇ) ve 19. Modül (BİTİŞ) ile ilgili depo klasörlerinin bağlantılarını aşağıdaki tabloda bulabilirsiniz.

Codelab

Python 2

Python 3

Modül 18

code

(yok)

19. Modül (bu codelab)

code

(Yukarıda belirtildiği gibi app.yaml dosyasını güncellemediyseniz app3.yaml kullanmanız dışında Python 2 ile aynıdır.)

Online referanslar

Bu eğitimle ilgili kaynakları aşağıda bulabilirsiniz:

App Engine görev sırası

Cloud Pub/Sub

App Engine NDB ve Cloud NDB (Datastore)

App Engine platformu

Diğer Cloud bilgileri

Videolar

Lisans

Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.