الترحيل من مهام الدفع في قائمة انتظار مهام App Engine إلى مهام السحابة الإلكترونية (الوحدة 8)

1. نظرة عامة

تهدف سلسلة الدروس التطبيقية حول الترميز بدون خادم (البرامج التعليمية العملية) والفيديوهات ذات الصلة إلى مساعدة مطوّري Google Cloud الذين لا يستخدمون خوادم على تحديث تطبيقاتهم من خلال إرشادهم خلال عملية واحدة أو أكثر من عمليات نقل البيانات، بعيدًا عن الخدمات القديمة في المقام الأول. يؤدي ذلك إلى تسهيل حمل التطبيقات وتوفير المزيد من الخيارات والمرونة، ما يتيح لك الدمج مع مجموعة أكبر من منتجات Cloud والوصول إليها والترقية بسهولة إلى الإصدارات الأحدث باللغات. مع تركيزنا في البداية على مستخدمي Cloud الأوائل، لا سيما مطوّري App Engine (البيئة العادية)، فإنّ هذه السلسلة واسعة بما يكفي لتشمل أنظمة أساسية أخرى بدون خادم، مثل Cloud Functions وCloud Run أو أي منصة أخرى إن وُجدت.

الغرض من هذا الدرس التطبيقي حول الترميز هو توضيح كيفية الانتقال من قائمة انتظار مهام App Engine (دفع المهام) إلى Cloud Tasks لمطوّري Python 2 App Engine. هناك أيضًا نقل بيانات ضمني من NDB في App Engine إلى Cloud NDB للوصول إلى مخزن البيانات (تتناول الوحدة بشكل أساسي في الوحدة رقم 2).

أضفنا استخدامه لمهام الدفع في الوحدة 7، ونُقل هذا الاستخدام إلى "مهام Cloud" هنا في الوحدة 8، ثم ننتقل إلى Python 3 وCloud Datastore في الوحدة 9. سيتم نقل بيانات المستخدمين الذين يستخدمون قوائم انتظار المهام لتنفيذ المهام السحب إلى Cloud Pub/Sub، ويجب الرجوع إلى الوحدات من 18 إلى 19 بدلاً من ذلك.

ستتعرَّف على كيفية إجراء ما يلي:

المتطلبات

استطلاع

كيف ستستخدم هذا البرنامج التعليمي؟

قراءة النص فقط اقرأها وأكمِل التمارين

كيف تقيّم تجربتك مع Python؟

حديث متوسط بارع

ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud؟

حديث متوسط بارع

2. الخلفية

تدعم قائمة انتظار مهام App Engine كلاً من مهام الدفع والسحب. لتحسين إمكانية نقل التطبيقات، ينصح فريق Google Cloud بالنقل من الخدمات المجمّعة القديمة مثل "قائمة انتظار المهام" إلى خدمات أخرى مكافئة من جهات خارجية أو مستقلة في السحابة الإلكترونية.

تتم تغطية نقل مهام السحب في وحدات النقل 18-19، بينما تركز الوحدات من 7 إلى 9 على نقل مهام الدفع. لنقل البيانات من مهام إرسال قائمة انتظار مهام App Engine، أضفنا استخدامه إلى نموذج تطبيق Python 2 App Engine الحالي الذي يسجّل زيارات الصفحة الجديدة ويعرض أحدث الزيارات. يضيف الدرس التطبيقي حول ترميز الوحدة 7 مهمة فورية لحذف الزيارات الأقدم، إذ لن تظهر مرة أخرى مطلقًا، فلماذا يجب أن تشغل مساحة تخزين إضافية في Datastore؟ يحافظ هذا الدرس التطبيقي حول ترميز الوحدة 8 على نفس الوظيفة، ولكنه ينقل آلية الانتظار الأساسية من مهام الإرسال في قائمة انتظار المهام إلى مهام Cloud، بالإضافة إلى تكرار نقل الوحدة 2 من App Engine NDB إلى Cloud NDB للوصول إلى Datastore.

يتضمن هذا الدليل التوجيهي الخطوات التالية:

  1. الإعداد/التمهيد
  2. تعديل الإعدادات
  3. تعديل رمز التطبيق

3- الإعداد/التمهيد

يوضّح هذا القسم كيفية تنفيذ ما يلي:

  1. إعداد مشروعك على Google Cloud
  2. الحصول على نموذج تطبيق أساسي
  3. (إعادة) نشر التطبيق الأساسي والتحقّق من صحته
  4. تفعيل خدمات Google Cloud/واجهات برمجة التطبيقات الجديدة

تضمن هذه الخطوات البدء باستخدام رمز صالح وأن نموذج التطبيق جاهز للنقل إلى خدمات السحابة الإلكترونية.

1. إعداد المشروع

إذا أكملت الدرس التطبيقي حول ترميز الوحدة 7، أعِد استخدام المشروع نفسه (والرمز البرمجي). ويمكنك بدلاً من ذلك إنشاء مشروع جديد أو إعادة استخدام مشروع حالي آخر. تأكَّد من أنّ المشروع يتضمّن حساب فوترة نشطًا وتطبيق App Engine مفعَّل. ابحث عن رقم تعريف مشروعك عندما تحتاج إلى أن يكون في متناول يدك خلال هذا الدرس التطبيقي حول الترميز، واستخدِمه كلما صادفت المتغيّر PROJECT_ID.

2. الحصول على نموذج تطبيق أساسي

أحد المتطلّبات الأساسية هو تطبيق App Engine للوحدة التنظيمية 7 قيد التشغيل: إكمال الدرس التطبيقي حول ترميز الوحدة 7 (يُنصح به) أو نسخ تطبيق الوحدة 7 من المستودع. وسواء كنت تستخدم موقعك أو يديك، فإن رمز الوحدة 7 هو المكان الذي سنبدأ فيه ("البدء"). يرشدك هذا الدرس التطبيقي حول الترميز خلال عملية النقل، وختامًا باستخدام رمز يشبه ما هو في مجلد Repo للوحدة 8 ("FINISH").

بغض النظر عن تطبيق الوحدة 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. (اختياري) يمكنك ضبط مشروعك على Google Cloud باستخدام gcloud config set project PROJECT_ID في حال كنت لا تريد إدخال PROJECT_ID مع كل أمر gcloud تصدره.
  4. نشر نموذج التطبيق باستخدام "gcloud app deploy"
  5. تأكَّد من أنّ التطبيق يعمل على النحو المتوقّع بدون أي مشكلة. إذا أكملت الدرس التطبيقي حول الترميز الخاص بالوحدة 7، سيعرض التطبيق أهم الزوّار إلى جانب أحدث الزيارات (الموضّحة أدناه). يظهر في أسفل الصفحة إشارة إلى المهام القديمة التي سيتم حذفها.

4aa8a2cb5f527079.png

4. تفعيل خدمات Google Cloud/واجهات برمجة التطبيقات الجديدة

كان التطبيق القديم يستخدم خدمات App Engine المجمّعة التي لا تتطلب إعدادًا إضافيًا، لكن خدمات Cloud المستقلة تتطلب ذلك، وسيستخدم التطبيق المحدَّث كلاً من "مهام Cloud" وCloud Datastore (عبر مكتبة عملاء Cloud NDB). هناك قيمة "مجانية دائمًا" لعدد من منتجات Cloud حصص الفئات، بما في ذلك App Engine وCloud Datastore ومهام Cloud. طالما أنك لا تتجاوز هذه الحدود، فلن تتحمل أي رسوم مقابل إكمال هذا البرنامج التعليمي. يمكن تفعيل Cloud APIs من Cloud Console أو من سطر الأوامر، حسب إعداداتك المفضَّلة.

من Cloud Console

انتقِل إلى صفحة "مكتبة مدير واجهة برمجة التطبيقات" (للمشروع الصحيح) في Cloud Console، وابحث عن Cloud Tasks API وCloud Tasks API باستخدام شريط البحث في منتصف الصفحة:

c7a740304e9d35b.png

انقر على الزر تفعيل لكل واجهة برمجة تطبيقات على حدة، وقد يُطلب منك تقديم معلومات الفوترة. هذا مثال يعرض صفحة Cloud Pub/Sub API Library (يجب عدم تفعيل واجهة Pub/Sub API لهذا الدرس التطبيقي حول الترميز، حيث يتم فقط عرض "مهام Cloud" و"مخزن البيانات"):

1b6c0a2a73124f6b.jpeg

من سطر الأوامر

وعلى الرغم من كونها غنية بالمعلومات المرئية لتمكين واجهات برمجة التطبيقات من وحدة التحكم، يفضل البعض سطر الأوامر. أصدر الأمر gcloud services enable cloudtasks.googleapis.com datastore.googleapis.com لتفعيل واجهتَي برمجة التطبيقات في الوقت نفسه:

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

قد يُطلَب منك إدخال معلومات الفوترة. إذا كنت ترغب في تفعيل واجهات برمجة تطبيقات Cloud أخرى وترغب في معرفة "معرّفات الموارد المنتظمة" (URI) الخاصة بها يمكن العثور عليها أسفل كل صفحة من صفحات "المكتبة" في كل واجهة برمجة تطبيقات. على سبيل المثال، يجب الانتباه إلى pubsub.googleapis.com باعتباره "اسم الخدمة" في أسفل صفحة النشر/الاشتراك أعلاه.

بعد اكتمال الخطوات، سيتمكّن مشروعك من الوصول إلى واجهات برمجة التطبيقات. حان الوقت الآن لتحديث التطبيق من أجل استخدام واجهات برمجة التطبيقات هذه.

4. تعديل الإعدادات

ويرجع سبب التعديلات التي تم إجراؤها في الإعدادات بشكل صريح إلى الاستخدام الإضافي لمكتبات عملاء السحابة الإلكترونية. بغض النظر عن التطبيقات التي تستخدمها، يجب إجراء التغييرات نفسها على التطبيقات التي لا تستخدم أي مكتبات لعملاء Cloud.

requirements.txt

تتبادل الوحدة 8 استخدام NDB في App Engine وقائمة انتظار المهام من الوحدة 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" بعد، يمكنك إنشاء قسم وإضافة كلتا المكتبتين على النحو التالي:

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 بمهام Cloud Tasks. ما مِن تغييرات على نموذج الويب، templates/index.html، إذ يجب أن يعمل كلا التطبيقَين بشكل متماثل ويعرض البيانات نفسها. يتم تقسيم التعديلات التي يتم إجراؤها على التطبيق الرئيسي إلى "المهام" الأربعة التالية:

  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. تتطلّب مكتبات عملاء السحابة الإلكترونية إعداد "برامج واجهة برمجة التطبيقات" وإنشاؤها. وتعيينهما إلى ds_client وts_client على التوالي.
  3. تنص مستندات قائمة انتظار المهام على ما يلي: "يوفّر App Engine قائمة انتظار تلقائية تُسمى default، وقد تم ضبطها وأصبحت جاهزة للاستخدام مع الإعدادات التلقائية". لا توفّر خدمة Cloud Tasks قائمة انتظار default (لأنّها منتج Cloud مستقل مستقل عن App Engine)، لذلك يجب استخدام رمز جديد لإنشاء قائمة انتظار في Cloud Tasks باسم "default".
  4. لا تتطلّب قائمة مهام App Engine تحديد منطقة لأنّها تستخدم المنطقة التي يعمل فيها تطبيقك. ومع ذلك، بما أنّ خدمة "مهام Google" أصبحت الآن منتجًا مستقلاً، فإنّها تتطلّب منطقة، ويجب أن تتطابق مع المنطقة التي يعمل فيها تطبيقك. يجب إدخال اسم المنطقة ورقم تعريف المشروع على Google Cloud لإنشاء "اسم مسار مؤهَّل بالكامل". كمعرف فريد لقائمة الانتظار.

تشكل التحديثات الموضحة في النقطة الثالثة والرابعة أعلاه الجزء الأكبر من الثوابت الإضافية والتهيئة المطلوبة. الاطّلاع على قسم "قبل" و"بعد" أدناه وإجراء هذه التغييرات في أعلى 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)

يعمل NDB مع App Engine وCloud NDB على نحو مماثل تقريبًا. لم تطرأ تغييرات كبيرة على نموذج البيانات أو في دالة store_visit(). الاختلاف الوحيد ملحوظًا هو أن إنشاء الكيان Visit في store_visit() أصبح الآن مضمنًا في كتلة with في Python. تتطلب منصة Cloud NDB أن يتم التحكم في جميع عمليات الوصول إلى مخزن البيانات من خلال مدير السياق، وبالتالي تشير إلى عبارة 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، واستخدام كليهما بإمكانيات مختلفة، مثل عرض المحتوى للمستخدم والإضافة إلى السجلات والتمرير إلى المعالج، وما إلى ذلك.
  4. يمكنك إنشاء مهمة إرسال فوري باستخدام هذا الطابع الزمني كحمولة لها و/trim كعنوان URL.
  5. في النهاية، يتم استدعاء معالج المهام من خلال HTTP POST إلى عنوان URL هذا.

يمكنك الاطّلاع على سير العمل هذا من خلال الصورة "قبل" مقتطف الرمز:

قبل:

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 داخل جزء with من Python (تكرار نقل بيانات الوحدة 2 إلى Cloud NDB)
  2. يمكنك إنشاء بيانات وصفية في "مهام Google" مع تضمين السمات المتوقّعة، مثل حمولة الطابع الزمني وعنوان 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، وبالتالي يجب تحليلها بتنسيق JSON عند الوصول.
  2. كان لطلب HTTP POST المسمّى /trim باستخدام قائمة انتظار المهام MIME من نوع 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- الملخّص/تنظيف البيانات

يلخّص هذا القسم هذا الدرس التطبيقي حول الترميز من خلال نشر التطبيق، والتأكّد من أنّه يعمل على النحو المطلوب وفي أي نتائج أخرى. بعد التحقق من صحة التطبيق، عليك إجراء أي عملية إزالة ومراعاة الخطوات التالية.

نشر التطبيق والتحقق منه

انشر تطبيقك باستخدام gcloud app deploy. من المفترض أن يكون الناتج متطابقًا تمامًا مع تطبيق الوحدة 7، ولكن يدرك أنك تغيرت تمامًا قائمة انتظار الدفع، ما يجعل تطبيقك أكثر قابلية للحمل من ذي قبل.

4aa8a2cb5f527079.png

تَنظيم

بنود عامة

إذا كنت قد انتهيت الآن، ننصحك بإيقاف تطبيق App Engine لتجنُّب تحمُّل تكلفة الفوترة. ومع ذلك، إذا أردت إجراء المزيد من الاختبارات أو التجارب، فمنصة App Engine لها حصة مجانية، ولن يتم تحصيل أي رسوم منك طالما أنك لا تتجاوز فئة الاستخدام هذه. هذه المعلومات متعلقة بالحوسبة، ولكن قد يتم أيضًا فرض رسوم على خدمات App Engine ذات الصلة، لذا يُرجى التحقق من صفحة الأسعار للحصول على مزيد من المعلومات. وإذا كانت عملية النقل هذه تشمل خدمات Cloud أخرى، يتم تحصيل الرسوم منها بشكل منفصل. وفي كلتا الحالتين، يمكنك الاطّلاع على قسم "الدروس التطبيقية حول الترميز" إذا كان ذلك منطبقًا. أدناه.

للإفصاح الكامل عن المعلومات، يتحمّل النشر على منصة حوسبة بدون خادم في 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". إذا كان التطبيق مستضافًا في الولايات المتحدة الأمريكية

من ناحية أخرى، إذا كنت لا تريد مواصلة استخدام هذا التطبيق أو الدروس التطبيقية الأخرى ذات الصلة لنقل البيانات وأردت حذف جميع البيانات بالكامل، عليك إيقاف مشروعك.

خصوصيّة هذا الدرس التطبيقي حول الترميز

الخدمات المدرَجة أدناه هي خدمات فريدة لهذا الدرس التطبيقي حول الترميز. ارجع إلى وثائق كل منتج لمزيد من المعلومات:

الخطوات التالية

وبهذا نكون قد انتهينا من إرسال مهام الدفع في قائمة انتظار مهام App Engine إلى Cloud Tasks. إذا كنت مهتمًا بمواصلة نقل هذا التطبيق إلى Python 3 والانتقال بشكل أكبر إلى Cloud NDB من Cloud NDB، ننصحك إذًا باستخدام الوحدة 9.

يتوفّر Cloud NDB خصيصًا لمطوّري Python 2 App Engine، ما يوفّر تجربة مستخدم شبه متطابقة، إلا أنّ Cloud Datastore لديها مكتبة عملاء أصلية خاصة بها مصمَّمة خصيصًا للمستخدمين غير التابعين لـ App Engine أو المستخدمين الجُدد (Python 3) App Engine. ومع ذلك، نظرًا لتوفُّر Cloud NDB للغة Python 2 و3، ليس عليك نقل البيانات إلى Cloud Datastore.

يصل كل من Cloud NDB وCloud Datastore إلى خدمة "تخزين البيانات" (إن كان ذلك بطرق مختلفة)، لذا فإن السبب الوحيد الذي يدفعك إلى الانتقال إلى خدمة "تخزين البيانات في السحابة الإلكترونية" هو إذا كانت لديك تطبيقات أخرى، لا سيما تطبيقات غير تابعة لـ App Engine، تستخدم "أداة تخزين البيانات في السحابة الإلكترونية" وتريد توحيد معاييرها في مكتبة عملاء واحدة لخدمة "تخزين البيانات". ويتم أيضًا تنفيذ عملية النقل الاختياري هذه من Cloud NDB إلى Cloud Datastore بشكل مستقل (بدون قائمة انتظار المهام أو "مهام السحابة الإلكترونية") في الوحدة 3.

بالإضافة إلى الوحدات 3 و8 و9، تشمل وحدات نقل البيانات الأخرى التي تركّز على الانتقال من خدمات App Engine القديمة التي يجب أخذها في الاعتبار ما يلي:

لم يعد App Engine النظام الأساسي الوحيد بدون خوادم في Google Cloud. إذا كان لديك تطبيق App Engine صغير أو تطبيق ذو وظائف محدودة وتريد تحويله إلى خدمة مصغّرة مستقلة، أو إذا كنت تريد تقسيم تطبيق متجانس إلى عدة مكوّنات قابلة لإعادة الاستخدام، هذه هي الأسباب الوجيهة للانتقال إلى وظائف السحابة الإلكترونية. إذا أصبحت عملية التطوير جزءًا من سير عمل تطوير التطبيقات، خاصةً إذا كانت تتألف من مسار CI/CD (التكامل المستمر أو العرض أو النشر المستمر)، ننصحك بنقل البيانات إلى تشغيل السحابة الإلكترونية. تغطي الوحدات التالية هذه السيناريوهات:

  • نقل البيانات من App Engine إلى Cloud Functions: راجِع الوحدة 11.
  • نقل البيانات من App Engine إلى Cloud Run: راجِع الوحدة 4 لتضمين تطبيقك مع Docker، أو الوحدة 5 لتنفيذ ذلك بدون حاويات أو معلومات Docker أو Dockerfiles.

إنّ التبديل إلى نظام أساسي آخر بدون خادم هو إجراء اختياري، وننصحك بالتفكير في أفضل الخيارات لتطبيقاتك وحالات الاستخدام قبل إجراء أي تغييرات.

بغض النظر عن وحدة نقل البيانات التي تفكر فيها بعد ذلك، يمكن الوصول إلى كل محتوى محطة النقل بدون خادم (الدروس التطبيقية حول الترميز والفيديوهات ورمز المصدر [عند توفّره]) من خلال مستودع البرامج المفتوحة المصدر. يوفّر README الخاص بالمستودع أيضًا إرشادات حول عمليات نقل البيانات التي يجب أخذها في الاعتبار وأي "طلب" ذي صلة. لوحدات النقل.

7. مراجع إضافية

في ما يلي مراجع إضافية لمساعدة المطوّرين الذين يستكشفون وحدة نقل البيانات هذه أو وحدة النقل ذات الصلة بها وكذلك المنتجات ذات الصلة. يشمل ذلك أماكن لتقديم ملاحظات حول هذا المحتوى وروابط إلى التعليمات البرمجية ومستندات مختلفة قد تجدها مفيدة.

المشاكل/الملاحظات في الدروس التطبيقية حول الترميز

إذا وجدت أي مشاكل في هذا الدرس التطبيقي حول الترميز، يُرجى البحث عن مشكلتك أولاً قبل ملء النموذج. روابط للبحث وإنشاء مشاكل جديدة:

موارد نقل البيانات

يمكن العثور على روابط لمجلدات repo للوحدة 7 (START) والوحدة 8 (FINISH) في الجدول أدناه.

Codelab

Python 2

Python 3

الوحدة 7

الرموز البرمجية

code (الرمز) (غير مدرَج في هذا البرنامج التعليمي)

الوحدة 8 (هذا الدرس التطبيقي حول الترميز)

الرموز البرمجية

(لا ينطبق)

مراجع على الإنترنت

في ما يلي موارد على الإنترنت قد تكون ذات صلة بهذا البرنامج التعليمي:

قائمة مهام App Engine ومهام السحابة الإلكترونية

NDB وCloud NDB (مخزن بيانات) في App Engine

منصة App Engine

معلومات أخرى عن السحابة الإلكترونية

الفيديوهات

الترخيص

هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.