ย้ายข้อมูลจากงานพุชคิวงานของ App Engine ไปยัง Cloud Tasks (โมดูล 8)

1. ภาพรวม

ชุดโปรแกรม Codelab สำหรับการย้ายข้อมูลแบบ Serverless (บทแนะนำแบบลงมือทำด้วยตนเอง) และวิดีโอที่เกี่ยวข้องมีจุดประสงค์เพื่อช่วยให้นักพัฒนาแอป Google Cloud Serverless ปรับการดำเนินการให้ทันสมัยได้ด้วยคำแนะนำการย้ายข้อมูลอย่างน้อย 1 รายการ โดยให้ย้ายออกจากบริการเดิมเป็นหลัก การดำเนินการดังกล่าวทำให้แอปพกพาไปได้ทุกที่ รวมถึงมอบตัวเลือกและความยืดหยุ่นที่มากขึ้น ทำให้สามารถผสานรวมและเข้าถึงผลิตภัณฑ์ Cloud ที่หลากหลายยิ่งขึ้น และอัปเกรดเป็นรุ่นภาษาใหม่ๆ ได้ง่ายยิ่งขึ้น แม้ว่าในช่วงแรกจะมุ่งเน้นที่ผู้ใช้ Cloud รุ่นแรกสุด ซึ่งเป็นนักพัฒนา App Engine (สภาพแวดล้อมมาตรฐาน) เป็นหลัก แต่ชุดโซลูชันนี้ก็กว้างพอที่จะรวมแพลตฟอร์มแบบ Serverless อื่นๆ เช่น Cloud Functions และ Cloud Run หรือแพลตฟอร์มอื่นๆ ที่เกี่ยวข้อง

วัตถุประสงค์ของ Codelab นี้คือการแสดงให้นักพัฒนาซอฟต์แวร์ Python 2 App Engine ทราบวิธีย้ายข้อมูลจากคิวงานของ App Engine (งานแบบพุช) ไปยัง Cloud Tasks นอกจากนี้ยังมีการย้ายข้อมูลโดยนัยจาก App Engine NDB ไปยัง Cloud NDB สำหรับการเข้าถึง Datastore (โดยครอบคลุมอยู่ในโมดูล 2)

เราได้เพิ่มการใช้งานการพุชในโมดูล 7 และย้ายข้อมูลการใช้งานดังกล่าวไปยัง Cloud Tasks ที่นี่ในโมดูล 8 จากนั้นดำเนินการต่อไปยัง Python 3 และ Cloud Datastore ในโมดูล 9 ผู้ที่ใช้คิวงานสำหรับงานพุลจะย้ายข้อมูลไปยัง Cloud Pub/Sub และควรอ้างอิงโมดูล 18-19 แทน

คุณจะได้เรียนรู้วิธีต่อไปนี้

สิ่งที่ต้องมี

แบบสำรวจ

คุณจะใช้บทแนะนำนี้อย่างไร

โปรดอ่านเท่านั้น อ่านและทำแบบฝึกหัด

คุณจะให้คะแนนประสบการณ์การใช้งาน Python อย่างไร

มือใหม่ ระดับกลาง ผู้ชำนาญ

คุณจะให้คะแนนความพึงพอใจในการใช้บริการ Google Cloud อย่างไร

มือใหม่ ระดับกลาง ผู้ชำนาญ

2. ข้อมูลเบื้องต้น

คิวงานของ App Engine รองรับทั้งงานพุชและพุล หากต้องการปรับปรุงการถ่ายโอนแอปพลิเคชัน ทีม Google Cloud ขอแนะนำให้ย้ายข้อมูลจากบริการแพ็กเกจเดิม เช่น คิวงาน ไปยังบริการ Cloud แบบสแตนด์อโลนอื่นๆ หรือบริการของบุคคลที่สามที่เทียบเท่ากัน

การย้ายข้อมูลงานพุลอยู่ในโมดูลการย้ายข้อมูล 18-19 ขณะที่โมดูล 7-9 จะมุ่งเน้นที่การย้ายข้อมูลงานพุช เพื่อที่จะย้ายข้อมูลจากงานพุชคิวงานของ App Engine เราได้เพิ่มการใช้งานของแอปดังกล่าวลงในแอปตัวอย่าง Python 2 App Engine ที่มีอยู่ซึ่งจะบันทึกการเข้าชมหน้าเว็บใหม่และแสดงการเข้าชมล่าสุด Codelab ของโมดูล 7 ได้เพิ่มงานพุชเพื่อลบการเข้าชมเก่าที่สุด และระบบจะไม่แสดงการเข้าชมเหล่านั้นอีก แล้วเหตุใดจึงต้องใช้พื้นที่เก็บข้อมูลเพิ่มเติมใน Datastore Codelab ของโมดูล 8 นี้จะรักษาฟังก์ชันการทำงานเดิม แต่จะย้ายกลไกการจัดคิวที่สำคัญจากงานพุชคิวงานไปยัง Cloud Tasks รวมถึงย้ายข้อมูลโมดูล 2 ซ้ำจาก App Engine NDB ไปยัง Cloud NDB เพื่อเข้าถึง Datastore

บทแนะนำนี้มีขั้นตอนต่อไปนี้

  1. การตั้งค่า/งานล่วงหน้า
  2. อัปเดตการกำหนดค่า
  3. แก้ไขโค้ดของแอปพลิเคชัน

3. การตั้งค่า/งานล่วงหน้า

ส่วนนี้จะอธิบายวิธี:

  1. ตั้งค่าโปรเจ็กต์ที่อยู่ในระบบคลาวด์
  2. รับแอปตัวอย่างพื้นฐาน
  3. (อีกครั้ง) ติดตั้งใช้งานและตรวจสอบแอปพื้นฐาน
  4. เปิดใช้บริการ/API ใหม่ของ Google Cloud

ขั้นตอนเหล่านี้จะช่วยให้มั่นใจว่าคุณเริ่มต้นด้วยโค้ดที่ใช้งานได้ และแอปตัวอย่างของคุณพร้อมสำหรับการย้ายข้อมูลไปยังบริการระบบคลาวด์

1. สร้างโปรเจ็กต์

หากคุณทำ Codelab ของโมดูล 7 เสร็จแล้ว ให้ใช้โปรเจ็กต์ (และโค้ด) เดียวกันนั้นซ้ำ หรือสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์อื่นที่มีอยู่ซ้ำ ตรวจสอบว่าโปรเจ็กต์มีบัญชีสำหรับการเรียกเก็บเงินที่ใช้งานอยู่และแอป App Engine ที่เปิดใช้แล้ว หารหัสโปรเจ็กต์ตามความต้องการเพื่อนำไปใช้ในระหว่าง Codelab นี้ โดยใช้เมื่อใดก็ตามที่คุณพบตัวแปร PROJECT_ID

2. รับแอปตัวอย่างพื้นฐาน

ข้อกำหนดเบื้องต้นอย่างหนึ่งคือแอป App Engine โมดูล 7 ที่ใช้งานได้ กล่าวคือ ทำ Codelab ของโมดูล 7 (แนะนำ) หรือคัดลอกแอปโมดูล 7 จากที่เก็บ ไม่ว่าคุณจะใช้โค้ดของคุณเองหรือของเรา โค้ดโมดูล 7 คือส่วนที่เราจะเริ่มต้น ("START") Codelab นี้จะแนะนำการย้ายข้อมูล สรุปด้วยโค้ดที่คล้ายคลึงกับสิ่งที่อยู่ในโฟลเดอร์ที่เก็บโมดูล 8 ("FINISH")

ไม่ว่าคุณจะใช้แอป Module 7 ใด โฟลเดอร์ควรมีลักษณะตามด้านล่าง ซึ่งอาจมีโฟลเดอร์ lib ด้วยเช่นกัน

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

3. (อีกครั้ง) ติดตั้งใช้งานและตรวจสอบแอปพื้นฐาน

ดำเนินการตามขั้นตอนต่อไปนี้เพื่อทำให้แอปโมดูล 7 ใช้งานได้

  1. ลบโฟลเดอร์ lib หากมี แล้วเรียกใช้ pip install -t lib -r requirements.txt เพื่อป้อนข้อมูล lib ใหม่ คุณอาจต้องใช้ pip2 แทน หากติดตั้งทั้ง Python 2 และ 3 ไว้ในเครื่องการพัฒนาแล้ว
  2. ตรวจสอบว่าคุณได้ติดตั้งและเริ่มต้นเครื่องมือบรรทัดคำสั่ง gcloud และตรวจสอบการใช้งานแล้ว
  3. (ไม่บังคับ) ให้ตั้งค่าโปรเจ็กต์ที่อยู่ในระบบคลาวด์ด้วย gcloud config set project PROJECT_ID หากไม่ต้องการป้อน PROJECT_ID ด้วยคำสั่ง gcloud แต่ละรายการที่คุณออก
  4. ทำให้แอปตัวอย่างใช้งานได้ด้วย gcloud app deploy
  5. ยืนยันว่าแอปทำงานตามที่คาดไว้โดยไม่มีปัญหา หากคุณทำ Codelab ของโมดูล 7 เสร็จสมบูรณ์แล้ว แอปจะแสดงผู้เข้าชมอันดับสูงสุดพร้อมกับการเข้าชมล่าสุด (ภาพด้านล่าง) ที่ด้านล่างจะบ่งบอกถึงงานเก่าที่จะถูกลบ

4aa8a2cb5f527079.png

4. เปิดใช้บริการ/API ใหม่ของ Google Cloud

แอปเดิมใช้บริการแพ็กเกจของ App Engine ซึ่งไม่ต้องมีการตั้งค่าเพิ่มเติม แต่บริการระบบคลาวด์แบบสแตนด์อโลนต้องใช้ทั้ง Cloud Tasks และ Cloud Datastore (ผ่านไลบรารีไคลเอ็นต์ Cloud NDB) ผลิตภัณฑ์ Cloud จำนวนมากจะมี "ฟรีไม่จำกัดเวลา" โควต้า ซึ่งรวมถึง App Engine, Cloud Datastore และ Cloud Tasks ตราบใดที่คุณยังใช้ไม่เกินขีดจำกัดดังกล่าว คุณไม่ควรเสียค่าใช้จ่ายเมื่อดูบทแนะนำนี้จนจบ เปิดใช้ Cloud APIs ได้จาก Cloud Console หรือจากบรรทัดคำสั่งก็ได้ ทั้งนี้ขึ้นอยู่กับค่ากำหนดของคุณ

จาก Cloud Console

ไปที่หน้าไลบรารีของตัวจัดการ API (สำหรับโปรเจ็กต์ที่ถูกต้อง) ใน Cloud Console แล้วค้นหา API ของ Cloud Datastore และ Cloud Tasks โดยใช้แถบค้นหาที่ตรงกลางหน้า

c7a740304e9d35b.png

คลิกปุ่มเปิดใช้สำหรับ API แต่ละรายการแยกกัน คุณอาจได้รับแจ้งให้ใส่ข้อมูลสำหรับการเรียกเก็บเงิน นี่คือตัวอย่างที่แสดงหน้าไลบรารี Cloud Pub/Sub API (อย่าเปิดใช้ Pub/Sub API สำหรับ Codelab นี้ แต่มีเพียง Cloud Tasks และ Datastore เท่านั้น)

1b6c0a2a73124f6b.jpeg

จากบรรทัดคำสั่ง

แม้ว่าฟีเจอร์นี้จะทำให้แสดง API ต่างๆ ได้จากคอนโซลอย่างชัดเจน แต่บางรายก็เลือกใช้บรรทัดคำสั่งมากกว่า ออกคำสั่ง gcloud services enable cloudtasks.googleapis.com datastore.googleapis.com เพื่อเปิดใช้ API ทั้งสองพร้อมกันดังนี้

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

ระบบอาจแจ้งให้คุณใส่ข้อมูลสำหรับการเรียกเก็บเงิน หากคุณต้องการเปิดใช้ Cloud API อื่นๆ และต้องการทราบเกี่ยวกับ "URL" ของ Cloud API สามารถดูได้ที่ด้านล่างของหน้าไลบรารีของ API แต่ละหน้า เช่น สังเกต pubsub.googleapis.com เป็น "ชื่อบริการ" ที่ด้านล่างของหน้า Pub/Sub ด้านบน

หลังจากทำตามขั้นตอนเรียบร้อยแล้ว โปรเจ็กต์จะเข้าถึง API ได้ ตอนนี้ถึงเวลาอัปเดตแอปเพื่อใช้ API เหล่านั้นแล้ว

4. อัปเดตการกำหนดค่า

การอัปเดตในการกำหนดค่าเกิดขึ้นอย่างชัดเจนเนื่องจากการใช้ไลบรารีของไคลเอ็นต์ระบบคลาวด์เพิ่มเข้ามา ไม่ว่าคุณจะใช้เวอร์ชันใดก็ตาม คุณต้องทำการเปลี่ยนแปลงเดียวกันนี้กับแอปที่ไม่ได้ใช้ไลบรารีของไคลเอ็นต์ Cloud ใดๆ

requirements.txt

โมดูล 8 จะแลกเปลี่ยนการใช้ App Engine NDB และคิวงานจากโมดูล 1 กับ Cloud NDB และ Cloud Tasks เพิ่ม google-cloud-ndb และ google-cloud-tasks ต่อท้าย requirements.txt เพื่อเข้าร่วม flask จากโมดูล 7:

flask
google-cloud-ndb
google-cloud-tasks

ไฟล์ requirements.txt นี้ไม่มีหมายเลขเวอร์ชันใดๆ ซึ่งหมายความว่าระบบจะเลือกเวอร์ชันล่าสุดไว้ หากมีความไม่สามารถทำงานร่วมกันได้ ให้ระบุหมายเลขเวอร์ชันเพื่อล็อกเวอร์ชันที่ใช้งานได้ของแอป

app.yaml

เมื่อใช้ไลบรารีของไคลเอ็นต์ Cloud รันไทม์ของ Python 2 App Engine จะต้องใช้แพ็กเกจของบุคคลที่สามที่เฉพาะเจาะจง ซึ่งได้แก่ grpcio และ setuptools ผู้ใช้ Python 2 ต้องแสดงไลบรารีในตัวในลักษณะนี้ร่วมกับเวอร์ชันที่มีอยู่หรือ "ล่าสุด" ใน app.yaml หากยังไม่มีส่วน libraries ให้สร้างส่วนดังกล่าวและเพิ่มไลบรารีทั้ง 2 รายการดังนี้

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

เมื่อย้ายข้อมูลแอปของคุณ แอปอาจมีส่วน libraries อยู่แล้ว หากมี grpcio และ setuptools ขาดหายไป เพียงเพิ่มรายการเหล่านี้ลงในส่วน libraries ที่มีอยู่ app.yaml ที่อัปเดตแล้วควรมีลักษณะดังนี้

runtime: python27
threadsafe: yes
api_version: 1

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

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

appengine_config.py

การเรียกใช้ google.appengine.ext.vendor.add() ใน appengine_config.py จะเชื่อมต่อไลบรารีของบุคคลที่สามที่คัดลอกมา (บางครั้งเรียกว่า "ผู้ให้บริการ" หรือ "การรวมกลุ่มอีเมลด้วยตนเอง") ใน lib กับแอปของคุณ ด้านบนใน app.yaml เราได้เพิ่มไลบรารีของบุคคลที่สามในตัว ซึ่งไลบรารีดังกล่าวจำเป็นต้องใช้ setuptools.pkg_resources.working_set.add_entry() ในการเชื่อมโยงแอปของคุณเข้ากับแพ็กเกจในตัวของ ดังกล่าว ใน lib ด้านล่างนี้คือโมดูล 1 เดิม appengine_config.py และหลังจากที่คุณอัปเดตโมดูล 8 แล้ว

ก่อนหน้า:

from google.appengine.ext import vendor

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

หลัง:

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)

นอกจากนี้ยังดูคำอธิบายที่คล้ายกันได้ในเอกสารประกอบการย้ายข้อมูล App Engine

5. แก้ไขโค้ดของแอปพลิเคชัน

ส่วนนี้จะแสดงการอัปเดตไฟล์แอปพลิเคชันหลัก main.py โดยแทนที่การใช้พุชคิวของ App Engine Task Queue ด้วย Cloud Tasks ไม่มีการเปลี่ยนแปลงกับเทมเพลตเว็บ templates/index.html ทั้ง 2 แอปควรทำงานเหมือนกันโดยแสดงข้อมูลเดียวกัน การแก้ไขแอปพลิเคชันหลักจะแบ่งออกเป็น 4 "สิ่งที่ต้องทำ" ดังนี้

  1. อัปเดตการนำเข้าและการเริ่มต้น
  2. อัปเดตฟังก์ชันการทำงานของโมเดลข้อมูล (Cloud NDB)
  3. ย้ายข้อมูลไปยัง Cloud Tasks (และ Cloud NDB)
  4. อัปเดตเครื่องจัดการงาน (พุช)

1. อัปเดตการนำเข้าและการเริ่มต้น

  1. โดยแทนที่ App Engine NDB (google.appengine.ext.ndb) และคิวงาน (google.appengine.api.taskqueue) ด้วย Cloud NDB (google.cloud.ndb) และ Cloud Tasks (google.cloud.tasks) ตามลำดับ
  2. ไลบรารีของไคลเอ็นต์ระบบคลาวด์จำเป็นต้องมีการเริ่มต้นและการสร้าง "ไคลเอ็นต์ API" มอบหมายให้ ds_client และ ts_client ตามลำดับ
  3. เอกสารประกอบของคิวงานจะระบุว่า "App Engine มีพุชคิวเริ่มต้นชื่อ default ซึ่งได้รับการกำหนดค่าและพร้อมใช้งานกับการตั้งค่าเริ่มต้นแล้ว" Cloud Tasks ไม่มีคิว default (เนื่องจากเป็นผลิตภัณฑ์ Cloud แบบสแตนด์อโลนที่ไม่เกี่ยวข้องกับ App Engine) ดังนั้นจึงต้องใช้โค้ดใหม่เพื่อสร้างคิว Cloud Tasks ที่ชื่อ default
  4. คิวงานของ App Engine ไม่ได้กำหนดให้คุณระบุภูมิภาคเนื่องจากใช้ภูมิภาคที่แอปของคุณทำงาน อย่างไรก็ตาม เนื่องจากขณะนี้ Cloud Tasks เป็นผลิตภัณฑ์อิสระ จึงจำเป็นต้องมีภูมิภาค และภูมิภาคดังกล่าวต้องตรงกับภูมิภาคที่แอปของคุณทำงานอยู่ ต้องระบุชื่อภูมิภาคและรหัสโปรเจ็กต์ที่อยู่ในระบบคลาวด์เพื่อสร้าง "ชื่อเส้นทางที่มีคุณสมบัติครบถ้วน" เป็นตัวระบุที่ไม่ซ้ำกันของคิว

การอัปเดตที่อธิบายไว้ในหัวข้อย่อยที่ 3 และ 4 ด้านบนจะประกอบไปด้วยค่าคงที่เพิ่มเติมและการเริ่มต้นที่จำเป็น ดูใน "ก่อน" และ "หลัง" ด้านล่างและทำการเปลี่ยนแปลงเหล่านี้ที่ด้านบนของ main.py

ก่อนหน้า:

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

app = Flask(__name__)

หลัง:

from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
from google.cloud import ndb, tasks

app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()

_, PROJECT_ID = google.auth.default()
REGION_ID = 'REGION_ID'    # replace w/your own
QUEUE_NAME = 'default'     # replace w/your own
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION_ID, QUEUE_NAME)

2. อัปเดตฟังก์ชันการทำงานของโมเดลข้อมูล (Cloud NDB)

App Engine NDB และ Cloud NDB ทำงานเกือบจะเหมือนกัน ไม่มีการเปลี่ยนแปลงที่สำคัญกับโมเดลข้อมูลและฟังก์ชัน store_visit() ความแตกต่างเพียงอย่างเดียวที่สังเกตเห็นได้คือการสร้างเอนทิตี Visit ใน store_visit() จะรวมอยู่ในบล็อก Python with Cloud NDB กำหนดให้มีการควบคุมการเข้าถึง Datastore ทั้งหมดภายในเครื่องมือจัดการบริบท ดังนั้นคำสั่ง with ข้อมูลโค้ดด้านล่างแสดงความแตกต่างเล็กน้อยนี้เมื่อย้ายข้อมูลไปยัง Cloud NDB ใช้การเปลี่ยนแปลงนี้

ก่อนหน้า:

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 entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

หลัง:

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 entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

3. ย้ายข้อมูลไปยัง Cloud Tasks (และ Cloud NDB)

การเปลี่ยนแปลงที่สำคัญที่สุดในการย้ายข้อมูลนี้จะเปลี่ยนโครงสร้างพื้นฐานสำหรับคิวที่ใช้งานอยู่ โดยการดำเนินการนี้จะเกิดขึ้นในฟังก์ชัน fetch_visits() ซึ่งเป็นการสร้างงาน (พุช) เพื่อลบการเข้าชมเก่าและจัดคิวสำหรับการดำเนินการ อย่างไรก็ตาม ฟังก์ชันเดิมจากโมดูล 7 จะยังคงเดิม ดังนี้

  1. การค้นหาการเข้าชมล่าสุด
  2. บันทึกการประทับเวลาของ Visit ล่าสุดซึ่งแสดงที่เก่าที่สุดแทนการแสดงการเข้าชมเหล่านั้นโดยทันที ซึ่งคุณสามารถลบการเข้าชมทั้งหมดที่เก่ากว่านี้ได้อย่างปลอดภัย
  3. แสดงการประทับเวลาเป็นแบบลอยและสตริงโดยใช้ยูทิลิตี Python มาตรฐานและใช้ทั้ง 2 ขนาดในความจุที่หลากหลาย เช่น แสดงต่อผู้ใช้ เพิ่มในบันทึก ส่งไปยังตัวแฮนเดิล เป็นต้น
  4. สร้างงานพุชที่มีการประทับเวลานี้เป็นเพย์โหลด พร้อมด้วย /trim เป็น URL
  5. เครื่องจัดการงานจะเรียกไปยัง URL นั้นผ่าน HTTP POST

ขั้นตอนการทำงานนี้จะแสดงเป็นรูปภาพ "ก่อน" ข้อมูลโค้ด:

ก่อนหน้า:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    data = Visit.query().order(-Visit.timestamp).fetch(limit)
    oldest = time.mktime(data[-1].timestamp.timetuple())
    oldest_str = time.ctime(oldest)
    logging.info('Delete entities older than %s' % oldest_str)
    taskqueue.add(url='/trim', params={'oldest': oldest})
    return data, oldest_str

แม้ว่าฟังก์ชันการทำงานจะยังคงเหมือนเดิม Cloud Tasks จะกลายเป็นแพลตฟอร์มการดำเนินการ การอัปเดตเพื่อให้การเปลี่ยนแปลงนี้มีผล ได้แก่

  1. รวมการค้นหา Visit ภายในบล็อก Python with (การย้ายข้อมูลโมดูล 2 ซ้ำไปยัง Cloud NDB)
  2. สร้างข้อมูลเมตาของ Cloud Tasks รวมถึงแอตทริบิวต์ที่คาดไว้ เช่น เพย์โหลดการประทับเวลาและ URL จากนั้นเพิ่มประเภท MIME และเข้ารหัส JSON ให้กับเพย์โหลดด้วย
  3. ใช้ไคลเอ็นต์ Cloud Tasks API เพื่อสร้างงานที่มีข้อมูลเมตาและชื่อเส้นทางแบบเต็มของคิว

ดูภาพประกอบการเปลี่ยนแปลงของ fetch_visits() ได้ที่ด้านล่าง

หลัง:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    with ds_client.context():
        data = Visit.query().order(-Visit.timestamp).fetch(limit)
    oldest = time.mktime(data[-1].timestamp.timetuple())
    oldest_str = time.ctime(oldest)
    logging.info('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    ts_client.create_task(parent=QUEUE_PATH, task=task)
    return data, oldest_str

4. อัปเดตเครื่องจัดการงาน (พุช)

ฟังก์ชันตัวแฮนเดิลงาน (แบบพุช) ไม่ต้องใช้การอัปเดตครั้งใหญ่ ก็ต้องมีการดำเนินการเท่านั้น การตั้งค่านี้จะใช้ได้กับคิวงานหรือ Cloud Tasks "รหัสคือโค้ด" เขาจึงกล่าวกันว่า แต่จะมีการเปลี่ยนแปลงเล็กน้อยดังนี้

  1. เพย์โหลดการประทับเวลาถูกส่งแบบคำต่อคำไปยังคิวงาน แต่มีการเข้ารหัส JSON สำหรับ Cloud Tasks ดังนั้นจึงต้องมีการแยกวิเคราะห์ JSON เมื่อมาถึง
  2. การเรียก HTTP POST ไปยัง /trim ที่มีคิวงานมี MIMEtype โดยนัยเป็น application/x-www-form-urlencoded แต่สำหรับ Cloud Tasks จะได้รับการระบุอย่างชัดเจนว่าเป็น application/json ดังนั้นการดึงเพย์โหลดจึงมีวิธีที่แตกต่างเล็กน้อย
  3. ใช้เครื่องมือจัดการบริบทไคลเอ็นต์ Cloud NDB API (การย้ายข้อมูลโมดูล 2 ไปยัง Cloud NDB)

ด้านล่างนี้คือข้อมูลโค้ดก่อนและหลังทำการเปลี่ยนแปลงเหล่านี้กับเครื่องจัดการงาน trim()

ก่อนหน้า:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = request.form.get('oldest', type=float)
    keys = Visit.query(
            Visit.timestamp < datetime.fromtimestamp(oldest)
    ).fetch(keys_only=True)
    nkeys = len(keys)
    if nkeys:
        logging.info('Deleting %d entities: %s' % (
                nkeys, ', '.join(str(k.id()) for k in keys)))
        ndb.delete_multi(keys)
    else:
        logging.info('No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

หลัง:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = float(request.get_json().get('oldest'))
    with ds_client.context():
        keys = Visit.query(
                Visit.timestamp < datetime.fromtimestamp(oldest)
        ).fetch(keys_only=True)
        nkeys = len(keys)
        if nkeys:
            logging.info('Deleting %d entities: %s' % (
                    nkeys, ', '.join(str(k.id()) for k in keys)))
            ndb.delete_multi(keys)
        else:
            logging.info(
                    'No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

ไม่มีการอัปเดตเครื่องจัดการแอปพลิเคชันหลัก root() หรือเทมเพลตเว็บ templates/index.html

6. สรุป/ล้างข้อมูล

ส่วนนี้จะสรุป Codelab นี้โดยการทำให้แอปใช้งานได้ ซึ่งจะช่วยยืนยันว่าแอปทำงานได้ตามที่ต้องการและอยู่ในเอาต์พุตที่แสดงขึ้น หลังจากตรวจสอบแอปแล้ว ให้ล้างข้อมูลและพิจารณาขั้นตอนถัดไป

ติดตั้งใช้งานและยืนยันแอปพลิเคชัน

ทำให้แอปใช้งานได้ด้วย gcloud app deploy เอาต์พุตควรจะเหมือนกับแอปโมดูล 7 แต่กลับพบว่าคุณได้เปลี่ยนไปใช้ผลิตภัณฑ์พุชคิวที่ต่างจากเดิมอย่างสิ้นเชิง ทำให้แอปพกพาสะดวกขึ้นกว่าแต่ก่อน

4aa8a2cb5f527079.png

ล้างข้อมูล

ทั่วไป

หากดำเนินการเสร็จแล้ว เราขอแนะนำให้คุณปิดใช้แอป App Engine เพื่อหลีกเลี่ยงการเรียกเก็บเงิน อย่างไรก็ตาม หากคุณต้องการทดสอบหรือทดลองเพิ่มเติม แพลตฟอร์ม App Engine จะมีโควต้าฟรี และตราบใดที่คุณใช้งานไม่เกินระดับการใช้งานดังกล่าว เราก็จะไม่เรียกเก็บเงิน ค่าดังกล่าวมีไว้สําหรับการประมวลผล แต่ก็อาจมีการเรียกเก็บเงินค่าบริการ App Engine ที่เกี่ยวข้องด้วย ดังนั้นโปรดดูข้อมูลเพิ่มเติมในหน้าราคา หากการย้ายข้อมูลนี้เกี่ยวข้องกับบริการระบบคลาวด์อื่นๆ ระบบจะเรียกเก็บเงินแยกต่างหาก ในทั้ง 2 กรณี หากมี โปรดดูส่วน "เฉพาะสำหรับ Codelab นี้" ด้านล่าง

เพื่อการเปิดเผยข้อมูลทั้งหมด การทำให้ใช้งานได้กับแพลตฟอร์มการประมวลผลแบบ Serverless ของ Google Cloud อย่าง App Engine จะมีค่าใช้จ่ายในการสร้างและพื้นที่เก็บข้อมูลเล็กน้อย Cloud Build มีโควต้าฟรีของตนเอง เช่นเดียวกับ Cloud Storage พื้นที่เก็บข้อมูลของรูปภาพจะใช้โควต้านั้นหมด อย่างไรก็ตาม คุณอาจอาศัยอยู่ในภูมิภาคที่ไม่มีรุ่นฟรีดังกล่าว โปรดระวังการใช้พื้นที่เก็บข้อมูลของคุณเพื่อลดค่าใช้จ่ายที่อาจเกิดขึ้น "โฟลเดอร์" เฉพาะของ Cloud Storage ที่คุณควรตรวจสอบมีดังนี้

  • 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
  • ลิงก์พื้นที่เก็บข้อมูลด้านบนขึ้นอยู่กับ PROJECT_ID และ *LOC*ของคุณ เช่น "us" หากแอปของคุณโฮสต์ในสหรัฐอเมริกา

ในทางกลับกัน หากคุณไม่ต้องการดำเนินการกับแอปพลิเคชันนี้หรือ Codelab การย้ายข้อมูลอื่นๆ ที่เกี่ยวข้องต่อไป และต้องการลบทุกอย่างออกทั้งหมด ให้ปิดโปรเจ็กต์

เฉพาะสำหรับ Codelab นี้

บริการในรายการด้านล่างเป็นบริการเฉพาะสำหรับ Codelab นี้ โปรดดูข้อมูลเพิ่มเติมในเอกสารประกอบของผลิตภัณฑ์แต่ละรายการ

  • Cloud Tasks มีรุ่นฟรี ดูรายละเอียดเพิ่มเติมในหน้าราคา
  • บริการ App Engine Datastore ให้บริการโดย Cloud Datastore (Cloud Firestore ในโหมด Datastore) ซึ่งมีรุ่นฟรีเช่นกัน ดูข้อมูลเพิ่มเติมได้ที่หน้าราคา

ขั้นตอนถัดไป

การย้ายข้อมูลจากคิวงานของ App Engine จะพุชงานไปยัง Cloud Tasks เป็นการสรุปข้อมูล หากสนใจที่จะย้ายแอปนี้ไปยัง Python 3 ต่อไปและย้ายข้อมูลไปยัง Cloud Datastore จาก Cloud NDB ต่อไป โปรดพิจารณาโมดูล 9

Cloud NDB มีไว้สำหรับนักพัฒนา Python 2 App Engine โดยเฉพาะ ซึ่งมอบประสบการณ์ของผู้ใช้แทบจะเหมือนกัน แต่ Cloud Datastore มีไลบรารีไคลเอ็นต์แบบเนทีฟที่สร้างขึ้นสำหรับผู้ใช้ที่ไม่ใช่ App Engine หรือผู้ใช้ App Engine (Python 3) รายใหม่ อย่างไรก็ตาม เนื่องจาก Cloud NDB ใช้งานได้กับ Python 2 และ 3 จึงไม่จำเป็นต้องย้ายข้อมูลไปยัง Cloud Datastore

Cloud NDB และ Cloud Datastore ต่างก็เข้าถึง Datastore (แม้ว่าจะเป็นวิธีการที่แตกต่างกัน) เหตุผลเดียวที่ควรพิจารณาเปลี่ยนไปใช้ Cloud Datastore คือเมื่อคุณมีแอปอื่นๆ อยู่แล้ว โดยเฉพาะแอปที่ไม่ใช่ App Engine และใช้ Cloud Datastore และต้องการสร้างมาตรฐานในไลบรารีไคลเอ็นต์ Datastore รายการเดียว การย้ายข้อมูลที่ไม่บังคับจาก Cloud NDB ไปยัง Cloud Datastore นี้ยังครอบคลุมการย้ายข้อมูลเช่นกัน (ไม่มีคิวงานหรือ Cloud Tasks) ในโมดูล 3

นอกเหนือจากโมดูล 3, 8 และ 9 แล้ว โมดูลการย้ายข้อมูลอื่นๆ ที่มุ่งเน้นการย้ายออกจากบริการแบบกลุ่มเดิมของ App Engine รวมถึงพิจารณาสิ่งต่อไปนี้ด้วย

  • โมดูล 2: ย้ายข้อมูลจาก App Engine NDB ไปยัง Cloud NDB
  • โมดูล 12-13: ย้ายข้อมูลจาก App Engine Memcache ไปยัง Cloud Memorystore
  • โมดูล 15-16: ย้ายข้อมูลจาก App Engine Blobstore ไปยัง Cloud Storage
  • โมดูล 18-19: คิวงานของ App Engine (พุลงาน) ไปยัง Cloud Pub/Sub

App Engine ไม่ใช่แพลตฟอร์มแบบ Serverless เพียงแพลตฟอร์มเดียวใน Google Cloud อีกต่อไป หากคุณมีแอป App Engine ขนาดเล็กหรือแอปที่มีฟังก์ชันการทำงานที่จำกัดและต้องการเปลี่ยนเป็น Microservice แบบสแตนด์อโลน หรือต้องการแตกแอปโมโนลิธให้เป็นคอมโพเนนต์ที่ใช้ซ้ำได้หลายรายการ เหตุผลที่ดีเหล่านี้ควรพิจารณาเปลี่ยนไปใช้ Cloud Functions หากการขนส่งด้วยคอนเทนเนอร์เป็นส่วนหนึ่งของเวิร์กโฟลว์การพัฒนาแอปพลิเคชัน โดยเฉพาะอย่างยิ่งหากประกอบด้วยไปป์ไลน์ CI/CD (การรวมอย่างต่อเนื่อง/การส่งมอบหรือการติดตั้งใช้งานอย่างต่อเนื่อง) ให้ลองย้ายข้อมูลไปยัง Cloud Run สถานการณ์เหล่านี้ครอบคลุมในโมดูลต่อไปนี้

  • ย้ายข้อมูลจาก App Engine ไปยัง Cloud Functions: ดูโมดูล 11
  • ย้ายข้อมูลจาก App Engine ไปยัง Cloud Run: ดูโมดูล 4 เพื่อสร้างคอนเทนเนอร์แอปด้วย Docker หรือโมดูล 5 เพื่อดำเนินการดังกล่าวโดยไม่ต้องมีคอนเทนเนอร์ ไม่มีความรู้เกี่ยวกับ Docker หรือDockerfile

คุณจะเปลี่ยนไปใช้แพลตฟอร์มแบบ Serverless อื่นหรือไม่ก็ได้ และเราขอแนะนำให้พิจารณาตัวเลือกที่ดีที่สุดสำหรับแอปและ Use Case ของคุณก่อนทำการเปลี่ยนแปลงใดๆ

ไม่ว่าคุณจะพิจารณาโมดูลการย้ายข้อมูลใดในครั้งถัดไป คุณสามารถเข้าถึงเนื้อหาของสถานีย้ายข้อมูลแบบ Serverless (โค้ดแล็บ วิดีโอ ซอร์สโค้ด [เมื่อพร้อมให้บริการ]) ทั้งหมดได้ที่ที่เก็บโอเพนซอร์ส README ของที่เก็บยังให้คำแนะนำเกี่ยวกับการย้ายข้อมูลที่ควรพิจารณาและ "คำสั่ง" ที่เกี่ยวข้อง โมดูลการย้ายข้อมูล

7. แหล่งข้อมูลเพิ่มเติม

รายการด้านล่างนี้เป็นแหล่งข้อมูลเพิ่มเติมสำหรับนักพัฒนาซอฟต์แวร์ที่ศึกษาเพิ่มเติมเกี่ยวกับโมดูลการย้ายข้อมูลนี้หรือที่เกี่ยวข้อง รวมถึงผลิตภัณฑ์ที่เกี่ยวข้อง ซึ่งรวมถึงพื้นที่สำหรับแสดงความคิดเห็นเกี่ยวกับเนื้อหานี้ ลิงก์ไปยังโค้ด และเอกสารประกอบต่างๆ ที่อาจเป็นประโยชน์กับคุณ

ปัญหา/ความคิดเห็นของ Codelab

หากมีปัญหาใดๆ เกี่ยวกับ Codelab นี้ โปรดค้นหาปัญหาของคุณก่อนยื่น ลิงก์สำหรับค้นหาและสร้างปัญหาใหม่

ทรัพยากรการย้ายข้อมูล

คุณสามารถดูลิงก์ไปยังโฟลเดอร์ที่เก็บสำหรับโมดูล 7 (START) และโมดูล 8 (FINISH) ได้ในตารางด้านล่าง

Codelab

Python 2

Python 3

โมดูล 7

รหัส

รหัส (ไม่มีในบทแนะนำนี้)

โมดูล 8 (Codelab นี้)

รหัส

(ไม่มี)

แหล่งข้อมูลออนไลน์

ด้านล่างนี้คือแหล่งข้อมูลออนไลน์ที่อาจเกี่ยวข้องกับบทแนะนำนี้

คิวงานของ App Engine และงานระบบคลาวด์

App Engine NDB และ Cloud NDB (พื้นที่เก็บข้อมูล)

แพลตฟอร์ม App Engine

ข้อมูลอื่นๆ เกี่ยวกับระบบคลาวด์

วิดีโอ

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0