1. نظرة عامة
تهدف سلسلة البرامج التعليمية حول Serverless Migration Station (برامج تعليمية ذاتية السرعة وعملية) ومقاطع الفيديو ذات الصلة إلى مساعدة مطوّري الحوسبة بدون خادم على Google Cloud في تحديث تطبيقاتهم من خلال إرشادهم خلال عملية نقل واحدة أو أكثر، مع التركيز بشكل أساسي على التخلّي عن الخدمات القديمة. يؤدي ذلك إلى زيادة قابلية نقل تطبيقاتك ويمنحك المزيد من الخيارات والمرونة، ما يتيح لك الدمج مع مجموعة أكبر من منتجات Cloud والوصول إليها، كما يسهّل عليك الترقية إلى أحدث إصدارات اللغة. على الرغم من أنّ هذه السلسلة تركّز في البداية على أوائل مستخدمي Cloud، وخاصةً مطوّري App Engine (البيئة العادية)، إلا أنّها واسعة النطاق بما يكفي لتشمل منصات أخرى بلا خادم، مثل Cloud Functions وCloud Run، أو في أي مكان آخر إذا كان ذلك منطبقًا.
الغرض من هذا الدرس التطبيقي حول الترميز هو توضيح كيفية نقل البيانات من "قائمة انتظار المهام" في App Engine (مهام الدفع) إلى Cloud Tasks لمطوّري تطبيقات Python 2 في App Engine. هناك أيضًا عملية نقل ضمنية من App Engine NDB إلى Cloud NDB للوصول إلى Datastore (يتم تناولها بشكل أساسي في الوحدة 2).
أضفنا استخدام مهام push في الوحدة 7، ونقلنا هذا الاستخدام إلى Cloud Tasks هنا في الوحدة 8، ثم واصلنا إلى Python 3 وCloud Datastore في الوحدة 9. سيتم نقل المستخدمين الذين يستعينون بـ "قوائم انتظار المهام" لتنفيذ مهام السحب إلى Cloud Pub/Sub، وعليهم الرجوع إلى الوحدتين 18 و19 بدلاً من ذلك.
ستتعرَّف على كيفية إجراء ما يلي:
- استبدال استخدام قائمة انتظار المهام في App Engine (مهام الدفع) بخدمة Cloud Tasks
- استبدال استخدام App Engine NDB بـ Cloud NDB (راجِع أيضًا الوحدة 2)
المتطلبات
- مشروع على السحابة الإلكترونية يتضمّن حساب فوترة نشطًا على Google Cloud
- مهارات أساسية في لغة Python
- معرفة عملية بالأوامر الشائعة على نظام التشغيل Linux
- معرفة أساسية بشأن تطوير ونشر تطبيقات App Engine
- تطبيق يعمل على الوحدة 7 من App Engine (أكمِل الدرس التطبيقي حول الترميز [يُنصح بذلك] أو انسخ التطبيق من المستودع)
استطلاع
كيف ستستخدم هذا البرنامج التعليمي؟
كيف تقيّم تجربتك مع Python؟
ما هو تقييمك لتجربة استخدام خدمات Google Cloud؟
2. الخلفية
تتيح قائمة انتظار المهام في App Engine مهام الدفع والسحب. لتحسين إمكانية نقل التطبيقات، ينصح فريق Google Cloud بالانتقال من الخدمات المجمّعة القديمة، مثل Task Queue، إلى خدمات أخرى مستقلة أو خدمات مكافئة تابعة لجهات خارجية.
- على مستخدمي مهام قائمة انتظار المهام التي يتم إرسالها نقل بياناتهم إلى مهام Cloud.
- على مستخدمي مهام قائمة انتظار المهام التي يتمسحبها نقل بياناتهم إلى Cloud Pub/Sub.
يتم تناول عملية نقل المهام من خلال السحب في الوحدتين 18 و19، بينما تركّز الوحدات من 7 إلى 9 على عملية نقل المهام من خلال الدفع. لنقل البيانات من مهام الدفع في "قائمة انتظار المهام" في App Engine، أضفنا استخدامها إلى نموذج تطبيق Python 2 App Engine الحالي الذي يسجّل زيارات الصفحات الجديدة ويعرض أحدث الزيارات. يضيف الدرس التطبيقي حول الترميز في الوحدة 7 مهمة دفع لحذف أقدم الزيارات، ولن يتم عرضها مرة أخرى، فلماذا يجب أن تشغل مساحة تخزين إضافية في مخزن البيانات؟ يحافظ الدرس التطبيقي حول الترميز هذا في الوحدة 8 على الوظيفة نفسها، ولكنّه ينقل آلية وضع المهام في قائمة الانتظار الأساسية من مهام الدفع في قائمة انتظار المهام إلى Cloud Tasks، بالإضافة إلى تكرار عملية نقل البيانات الوحدة 2 من App Engine NDB إلى Cloud NDB للوصول إلى مخزن البيانات.
يتضمّن هذا الدليل التعليمي الخطوات التالية:
- الإعداد/العمل التحضيري
- تعديل الإعدادات
- تعديل الرمز البرمجي للتطبيق
3- الإعداد/العمل التحضيري
يوضّح هذا القسم كيفية تنفيذ ما يلي:
- إعداد مشروعك على السحابة الإلكترونية
- الحصول على نموذج تطبيق أساسي
- (إعادة) نشر تطبيق أساسي وإثبات صحته
- تفعيل خدمات/واجهات برمجة تطبيقات جديدة في Google Cloud
تضمن هذه الخطوات أنّك تبدأ برمز برمجي يعمل وأنّ نموذج تطبيقك جاهز لنقله إلى خدمات Cloud.
1. إعداد المشروع
إذا أكملت الدرس التطبيقي حول الترميز للوحدة 7، أعِد استخدام المشروع (والرمز) نفسه. بدلاً من ذلك، يمكنك إنشاء مشروع جديد تمامًا أو إعادة استخدام مشروع حالي آخر. تأكَّد من أنّ المشروع يتضمّن حساب فوترة نشطًا وتطبيق App Engine مفعَّلاً. ابحث عن رقم تعريف مشروعك لأنّك ستحتاج إليه أثناء هذا الدرس التطبيقي حول الترميز، واستخدِمه كلّما صادفت المتغيّر PROJECT_ID.
2. الحصول على نموذج تطبيق أساسي
من المتطلبات الأساسية توفُّر تطبيق يعمل على الوحدة 7 من App Engine: أكمل الدرس التطبيقي حول الترميز الخاص بالوحدة 7 (يُنصح بذلك) أو انسخ تطبيق الوحدة 7 من المستودع. سواء استخدمت رمزك أو رمزنا، سنبدأ من رمز الوحدة 7 ("START"). يرشدك هذا الدرس التطبيقي حول الترميز خلال عملية نقل البيانات، وينتهي برمز يشبه الرمز الموجود في مجلد مستودع الوحدة التدريبية 8 ("FINISH").
- البدء: مستودع الوحدة التدريبية 7
- إنهاء: مستودع الوحدة التدريبية 8
- المستودع بأكمله (نسخ أو تنزيل ملف ZIP)
بغض النظر عن تطبيق الوحدة التدريبية 7 الذي تستخدمه، من المفترض أن يبدو المجلد كما هو موضّح أدناه، وربما يتضمّن مجلد lib أيضًا:
$ ls README.md appengine_config.py requirements.txt app.yaml main.py templates
3- (إعادة) نشر تطبيق أساسي وإثبات صحته
اتّبِع الخطوات التالية لنشر تطبيق الوحدة التدريبية 7:
- احذف المجلد
libإذا كان هناك مجلد، ثم شغِّلpip install -t lib -r requirements.txtلإعادة ملءlib. قد تحتاج إلى استخدامpip2بدلاً من ذلك إذا كان لديك كل من Python 2 و3 مثبّتَين على جهاز التطوير. - تأكَّد من أنّك ثبَّت وهيّأت أداة سطر الأوامر
gcloudوراجعت طريقة استخدامها. - (اختياري) اضبط مشروعك على السحابة الإلكترونية باستخدام
gcloud config set projectPROJECT_IDإذا كنت لا تريد إدخالPROJECT_IDمع كل أمرgcloudتصدره. - نشر نموذج التطبيق باستخدام
gcloud app deploy - تأكَّد من أنّ التطبيق يعمل على النحو المتوقّع بدون أي مشاكل. إذا أكملت الدرس التطبيقي حول الترميز 7، سيعرض التطبيق أهم الزوّار بالإضافة إلى أحدث الزيارات (كما هو موضّح أدناه). في أسفل الصفحة، يظهر إشارة إلى المهام الأقدم التي سيتم حذفها.

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

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

من سطر الأوامر
على الرغم من أنّ تفعيل واجهات برمجة التطبيقات من وحدة التحكّم يقدّم معلومات مرئية، يفضّل البعض استخدام سطر الأوامر. أدخِل الأمر 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 API أخرى ومعرفة "معرّفات الموارد المنتظمة" الخاصة بها، يمكنك العثور عليها في أسفل صفحة "المكتبة" لكل واجهة برمجة تطبيقات. على سبيل المثال، لاحظ pubsub.googleapis.com كـ "اسم الخدمة" في أسفل صفحة Pub/Sub أعلاه مباشرةً.
بعد إكمال الخطوات، سيتمكّن مشروعك من الوصول إلى واجهات برمجة التطبيقات. حان الوقت الآن لتحديث التطبيق لاستخدام واجهات برمجة التطبيقات هذه.
4. تعديل الإعدادات
تحدث التعديلات في الإعدادات بشكلٍ واضح بسبب الاستخدام الإضافي لمكتبات برامج Cloud. بغض النظر عن المكتبات التي تستخدمها، يجب إجراء التغييرات نفسها على التطبيقات التي لا تستخدم أيًا من مكتبات برامج Cloud.
requirements.txt
تستبدل الوحدة 8 استخدام App Engine NDB وTask Queue من الوحدة 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. في ما يلي appengine_config.py الأصلي للوحدة التدريبية 1 وبعد إجراء التعديلات على الوحدة التدريبية 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—يجب أن يعمل التطبيقان بشكلٍ مطابق، وأن يعرضا البيانات نفسها. يتم تقسيم التعديلات على التطبيق الرئيسي إلى أربع مهام على النحو التالي:
- تعديل عمليات الاستيراد والإعداد
- تعديل وظيفة نموذج البيانات (Cloud NDB)
- نقل البيانات إلى Cloud Tasks (وCloud NDB)
- معالج تعديل (إرسال) المهمة
1. تعديل عمليات الاستيراد والإعداد
- استبدِل App Engine NDB (
google.appengine.ext.ndb) وTask Queue (google.appengine.api.taskqueue) بـ Cloud NDB (google.cloud.ndb) وCloud Tasks (google.cloud.tasks) على التوالي. - تتطلّب مكتبات برامج Cloud إعداد وإنشاء "برامج API"، ويجب تعيينها إلى
ds_clientوts_clientعلى التوالي. - تنص مستندات "قائمة انتظار المهام" على ما يلي: "توفّر خدمة App Engine قائمة انتظار تلقائية للدفع، باسم
default، تم إعدادها وهي جاهزة للاستخدام مع الإعدادات التلقائية". لا توفّر Cloud Tasks قائمة انتظارdefault(لأنّها منتج مستقل من منتجات Cloud لا يرتبط بـ App Engine)، لذا يجب توفير رمز جديد لإنشاء قائمة انتظار Cloud Tasks باسمdefault. - لا تتطلّب "قائمة انتظار المهام" في App Engine منك تحديد منطقة لأنّها تستخدم المنطقة التي يتم تشغيل تطبيقك فيها. ومع ذلك، بما أنّ Cloud Tasks أصبح منتجًا مستقلاً، فهو يتطلّب منطقة، ويجب أن تتطابق هذه المنطقة مع المنطقة التي يعمل فيها تطبيقك. يجب توفير اسم المنطقة ورقم تعريف مشروع على السحابة الإلكترونية لإنشاء "اسم مسار مؤهَّل بالكامل" كمعرّف فريد للصف.
تشكّل التعديلات الموضّحة في النقطتين الثالثة والرابعة أعلاه الجزء الأكبر من الثوابت الإضافية وعملية التهيئة المطلوبة. يمكنك الاطّلاع على المثالين "قبل" و "بعد" أدناه وإجراء هذه التغييرات في أعلى 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() أصبح الآن مضمّنًا داخل كتلة with في Python. يتطلّب 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() حيث يتم إنشاء مهمة (push) لحذف الزيارات القديمة وإضافتها إلى قائمة الانتظار لتنفيذها. ومع ذلك، ستبقى الوظيفة الأصلية من الوحدة 7 كما هي:
- طلب البحث عن أحدث الزيارات
- بدلاً من عرض هذه الزيارات على الفور، احفظ الطابع الزمني لآخر
Visit، وهو الأقدم الذي يتم عرضه، ويمكنك حذف جميع الزيارات الأقدم من هذا الطابع الزمني. - استخرِج الطابع الزمني كعدد عشري وسلسلة باستخدام أدوات Python العادية، واستخدِم كليهما في مختلف الأغراض، مثل العرض للمستخدم والإضافة إلى السجلات والتمرير إلى المعالج وما إلى ذلك.
- أنشِئ مهمة إرسال باستخدام هذا الطابع الزمني كحمولة مع
/trimكعنوان URL. - يتم في النهاية استدعاء معالج المهام من خلال طلب 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 هي منصة التنفيذ. تشمل التعديلات التي تؤدي إلى هذا التغيير ما يلي:
- تضمين استعلام
Visitداخل كتلةwithفي Python (تكرار عملية نقل الوحدة 2 إلى Cloud NDB) - أنشئ بيانات وصفية لخدمة Cloud Tasks، بما في ذلك السمات المتوقّعة، مثل حمولة الطابع الزمني وعنوان URL، ولكن أضِف أيضًا نوع MIME ورمِّز الحمولة بتنسيق JSON.
- استخدِم برنامج 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. تعديل معالج المهام (push)
لا تتطلّب وظيفة معالج المهام (الدفع) إجراء تحديثات رئيسية، بل تتطلّب التنفيذ فقط. ينطبق ذلك على Task Queue أو Cloud Tasks. "الرمز هو الرمز"، كما يقولون. هناك بعض التغييرات الطفيفة، وهي:
- تم تمرير حمولة الطابع الزمني حرفيًا إلى Task Queue، ولكن تم ترميزها بتنسيق JSON في Cloud Tasks، وبالتالي يجب تحليلها بتنسيق JSON عند الوصول.
- كانت عملية استدعاء HTTP
POSTإلى/trimباستخدام "قائمة انتظار المهام" تتضمّن نوع MIME ضمنيًا وهوapplication/x-www-form-urlencoded، ولكن مع Cloud Tasks، يتم تحديد النوع بشكل صريح على أنّهapplication/json، لذا هناك طريقة مختلفة قليلاً لاستخراج الحمولة. - استخدِم أداة إدارة سياق عميل 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، ولكن ستلاحظ أنّك انتقلت إلى منتج مختلف تمامًا لقائمة انتظار الدفع، ما يجعل تطبيقك أكثر قابلية للنقل من ذي قبل.

تَنظيم
للجمهور العام
إذا انتهيت من استخدام التطبيق في الوقت الحالي، ننصحك بإيقاف تطبيق App Engine لتجنُّب تحمّل رسوم. ومع ذلك، إذا أردت إجراء المزيد من الاختبارات أو التجارب، تتضمّن منصة App Engine حصّة مجانية، وبالتالي لن يتم تحصيل رسوم منك طالما أنّك لا تتجاوز مستوى الاستخدام هذا. هذا السعر خاص بالحوسبة، ولكن قد تكون هناك رسوم أيضًا مقابل خدمات App Engine ذات الصلة، لذا يُرجى الاطّلاع على صفحة الأسعار للحصول على مزيد من المعلومات. إذا كان نقل البيانات هذا يتضمّن خدمات سحابية أخرى، يتم إصدار فواتير لها بشكل منفصل. في كلتا الحالتين، إذا كان ذلك منطبقًا، راجِع القسم "خاص بهذا الدرس التطبيقي حول الترميز" أدناه.
للتوضيح، يؤدي النشر على منصة حوسبة بدون خادم في Google Cloud، مثل App Engine، إلى تكبُّد تكاليف بسيطة للإنشاء والتخزين. تتضمّن Cloud Build حصة مجانية خاصة بها، وكذلك Cloud Storage. ويؤدي تخزين هذه الصورة إلى استهلاك جزء من هذه الحصة. ومع ذلك، قد تكون مقيمًا في منطقة لا تتوفّر فيها هذه الطبقة المجانية، لذا عليك الانتباه إلى استخدامك لمساحة التخزين لتقليل التكاليف المحتملة. تتضمّن "المجلدات" المحدّدة في Cloud Storage التي يجب مراجعتها ما يلي:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- تعتمد روابط مساحة التخزين أعلاه على
PROJECT_IDو *LOC*، على سبيل المثال، "us" إذا كان تطبيقك مستضافًا في الولايات المتحدة.
من ناحية أخرى، إذا كنت لن تواصل استخدام هذا التطبيق أو غيره من الدروس التعليمية البرمجية المتعلقة بنقل البيانات وأردت حذف كل شيء تمامًا، عليك إيقاف مشروعك.
خاص بهذا الدرس التطبيقي حول الترميز
الخدمات المدرَجة أدناه خاصة بهذا الدرس التطبيقي حول الترميز. يُرجى الرجوع إلى مستندات كل منتج للحصول على مزيد من المعلومات:
- تتوفّر في 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 بشكل منفصل (بدون Task Queue أو 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 Task Queue (مهام السحب) إلى Cloud Pub/Sub
لم تعُد App Engine هي المنصة الوحيدة بدون خادم في Google Cloud. إذا كان لديك تطبيق صغير على App Engine أو تطبيق بوظائف محدودة وتريد تحويله إلى خدمة مصغّرة مستقلة، أو إذا كنت تريد تقسيم تطبيق متكامل إلى عدة مكونات قابلة لإعادة الاستخدام، ستكون هذه أسبابًا وجيهة للنقل إلى Cloud Functions. إذا أصبحت عملية إنشاء الحاويات جزءًا من سير عمل تطوير التطبيقات، خاصةً إذا كانت تتألف من مسار CI/CD (التكامل المستمر/التسليم المتواصل أو النشر المستمر)، ننصحك بالانتقال إلى Cloud Run. تتناول الوحدات التدريبية التالية هذه السيناريوهات:
- نقل البيانات من App Engine إلى Cloud Functions: يمكنك الاطّلاع على الوحدة 11
- الانتقال من App Engine إلى Cloud Run: يمكنك الاطّلاع على الوحدة 4 لتضمين تطبيقك في حاوية باستخدام Docker، أو الوحدة 5 لإجراء ذلك بدون حاويات أو معرفة بـ Docker أو
Dockerfile
إنّ الانتقال إلى منصة أخرى بلا خادم هو أمر اختياري، وننصحك بمراجعة أفضل الخيارات لتطبيقاتك وحالات الاستخدام قبل إجراء أي تغييرات.
بغض النظر عن وحدة النقل التي ستختارها، يمكنك الوصول إلى كل محتوى Serverless Migration Station (الدروس البرمجية والفيديوهات ورمز المصدر [عند توفّره]) من خلال مستودع المصدر المفتوح. يوفّر مستودع README أيضًا إرشادات حول عمليات نقل البيانات التي يجب أخذها في الاعتبار وأي "ترتيب" ذي صلة لوحدات نقل البيانات.
7. مراجع إضافية
في ما يلي مراجع إضافية للمطوّرين الذين يريدون استكشاف هذه الوحدة أو وحدة نقل البيانات ذات الصلة بالإضافة إلى المنتجات ذات الصلة. ويشمل ذلك أماكن لتقديم ملاحظات حول هذا المحتوى، وروابط إلى الرمز، ومختلف أجزاء المستندات التي قد تجدها مفيدة.
مشاكل/ملاحظات بشأن الدروس التطبيقية حول الترميز
إذا واجهت أي مشاكل في هذا الدرس العملي، يُرجى البحث عن مشكلتك أولاً قبل إرسالها. روابط للبحث عن مشاكل جديدة وإنشائها:
مراجع لنقل البيانات
يمكنك العثور في الجدول أدناه على روابط لمجلدات المستودع الخاصة بالوحدة التدريبية 7 (البداية) والوحدة التدريبية 8 (النهاية).
Codelab | Python 2 | Python 3 |
الرمز (غير وارد في هذا الدليل التعليمي) | ||
الوحدة 8 (هذا الدرس التطبيقي حول الترميز) | (غير متوفر) |
مراجع متوفرة على الإنترنت
في ما يلي مراجع على الإنترنت قد تكون ذات صلة بهذا البرنامج التعليمي:
قائمة انتظار المهام في App Engine وCloud Tasks
- نظرة عامة على "قائمة مهام App Engine"
- نظرة عامة على قوائم انتظار الدفع في App Engine
- نقل مهام الدفع في App Engine Task Queue إلى Cloud Tasks
- نموذج مستندات حول مهام الدفع في "قائمة انتظار المهام" في App Engine إلى Cloud Tasks
- مستندات Cloud Tasks
- أمثلة على مكتبة برامج Python لخدمة Cloud Tasks
- معلومات أسعار Cloud Tasks
App Engine NDB وCloud NDB (تخزين البيانات)
- مستندات NDB في App Engine
- مستودع App Engine NDB
- مستندات Google Cloud NDB
- مستودع Google Cloud NDB
- معلومات أسعار Cloud Datastore
النظام الأساسي لـ App Engine
- مستندات App Engine
- وقت تشغيل Python 2 App Engine (البيئة العادية)
- استخدام المكتبات المضمّنة في App Engine على Python 2 App Engine
- وقت تشغيل Python 3 App Engine (البيئة العادية)
- الاختلافات بين أوقات تشغيل Python 2 و3 في App Engine (البيئة العادية)
- دليل نقل البيانات من Python 2 إلى Python 3 في App Engine (البيئة العادية)
- معلومات الأسعار والحصص في App Engine
- إطلاق الجيل الثاني من منصة App Engine (2018)
- مقارنة بين الجيل الأول والثاني من المنصات
- الدعم الطويل الأمد لأوقات التشغيل القديمة
- أمثلة على نقل المستندات
- عينات نقل البيانات التي يقدّمها المنتدى
معلومات أخرى حول السحابة الإلكترونية
- Python على Google Cloud Platform
- مكتبات برامج Python في Google Cloud
- فئة "دائمًا مجانية" في Google Cloud
- Google Cloud SDK (أداة سطر الأوامر
gcloud) - جميع مستندات Google Cloud
الفيديوهات
- Serverless Migration Station
- أداة "استكشافات" بدون خادم
- الاشتراك في قناة Google Cloud Tech
- الاشتراك في Google Developers
الترخيص
يخضع هذا العمل لترخيص المشاع الإبداعي مع نسب العمل إلى مؤلفه 2.0 Generic License.