كيفية استخدام App Engine Memcache في تطبيقات Flask (الوحدة 12)

1. نظرة عامة

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

يشرح لك هذا الدرس التطبيقي حول الترميز كيفية تضمين واستخدام App Engine Memcache في نموذج التطبيق من الدرس التطبيقي حول الترميز للوحدة 1. أضفنا استخدام Memcache في هذا البرنامج التعليمي للوحدة 12 ثم النقل إلى Cloud Memorystore بعد ذلك في الوحدة 13.

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

  • استخدام واجهة برمجة تطبيقات أو مكتبة Memcache في App Engine
  • إضافة التخزين المؤقت إلى تطبيق NDB الأساسي على Python 2 Flask

المتطلبات

استطلاع

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

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

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

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

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

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

2. الخلفية

لنقل البيانات من App Engine Memcache، أضِف استخدامه إلى Flask وتطبيق App Engine الحالي NDB الناتج عن الدرس التطبيقي حول الترميز للوحدة 1. يعرض نموذج التطبيق آخر عشر زيارات للمستخدم. إذا أجرى المستخدم نفسه تحديثًا للمتصفّح، ليس من الأفضل إنشاء كيانات "زيارات" جديدة باستمرار وجلب الزيارات الأخيرة من "مخزن البيانات"، وسيتم تخزين تلك الزيارات الأخيرة مؤقتًا.

وإذا وصل الزائر نفسه إلى الصفحة، سيتم عرض تلك الزيارات من ذاكرة التخزين المؤقت. إذا زار مستخدم جديد الموقع أو مرّت ساعة، يتم مسح ذاكرة التخزين المؤقت واستبدالها بأحدث الإدخالات (بالإضافة إلى زيارة جديدة مسجلة). من خلال تنفيذ تكامل App Engine Memcache هذا، يمكننا نقل النموذج إلى Cloud Memorystore في الدرس التالي (الوحدة 13) حول الترميز.

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

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

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

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

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

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

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

أحد المتطلبات الأساسية لهذا الدرس التطبيقي هو أن يكون لديك تطبيق نموذجي للوحدة 1 عامل. إذا لم يكن لديك حساب، فأكمل أحد البرامج التعليمية (الروابط أعلاه) قبل المتابعة هنا. أما إذا كنت على دراية بمحتوياتها، فما عليك سوى البدء برمز الوحدة 1 أدناه.

سنبدأ في استخدام رمز الوحدة 1، سواء كنت تستخدم موقعك أو تطبيقك. يرشدك الدرس التطبيقي هذا حول الترميز خلال كل خطوة، وينتهي بتعليمة برمجية تشبه ما هو موجود في مجلد Module 11 repo (FINISH).

يجب أن يبدو دليل ملفات بدء الوحدة 1 (الخاص بك أو بنا) على النحو التالي:

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

3- (إعادة) نشر التطبيق الأساسي

إليك الخطوات المتبقية لتنفيذ العمل المسبق الآن:

  1. التعرف مرة أخرى على أداة سطر الأوامر gcloud
  2. إعادة نشر نموذج التطبيق باستخدام "gcloud app deploy"
  3. التأكّد من تشغيل التطبيق على App Engine بدون مشكلة

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

a7a9d2b80d706a2b.png

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

لا يلزم إجراء أي تغييرات على ملفات إعداد App Engine العادية (app.yaml، وrequirements.txt، وappengine_config.py).

5- تعديل ملفات التطبيق

بما أنّنا نضيف فقط واجهة برمجة تطبيقات App Engine، فليس هناك حِزم خارجية معنيّة، ما يعني أنّه لا حاجة إلى تحديث ملفات الإعداد (app.yaml وrequirements.txt وappengine_config.py). هناك ملف تطبيق واحد فقط، main.py، لذا تؤثر جميع التغييرات في هذا القسم في هذا الملف فقط.

عمليات الاستيراد

الخطوة الأهم هي استيراد مكتبة Memcache، google.appengine.api.memcache. وبما أننا سنقوم بتخزين أحدث الزيارات مؤقتًا لمدة ساعة، فلنُضف أيضًا عددًا ثابتًا لعدد الثواني في الساعة. في ما يلي الشكل الذي كانت تظهر به الرمز لديك من قبل وهذا التغيير:

قبل:

from flask import Flask, render_template, request
from google.appengine.ext import ndb

app = Flask(__name__)

بعد:

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

app = Flask(__name__)
HOUR = 3600

إضافة التخزين المؤقت من خلال دعم Memcache

أهم تغيير هو إضافة استخدام التخزين المؤقت في تطبيقنا. وبشكل أكثر تحديدًا، ينبغي لنا الاحتفاظ بأحدث الزيارات في ذاكرة التخزين المؤقت، والتحقق مما إذا كانت الزيارات المخزنة مؤقتًا متاحة، ومحاولة استخدام النتائج المخزنة مؤقتًا قدر الإمكان وفقًا لخطتنا. في ما يلي الخطوات التي سيتخذها التطبيق لتحقيق هدفنا:

  1. تحديد الزيارة الحالية والتسميتها visitor
  2. محاولة استرجاع أحدث visits من ذاكرة التخزين المؤقت
  3. إذا كانت ذاكرة التخزين المؤقت فارغة أو كان الزائر الأخير (visits[0]['visitor']) مختلفًا عن visitor الحالي: يمكنك تخزين هذه الزيارة الجديدة، وجلب الزيارات الأخيرة، وتخزينها مؤقتًا لمدة ساعة.
  4. عرض visits للمستخدم من خلال نموذج الويب

في ما يلي الصورة المصغّرة قبل التعديل وبعده:

قبل:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

بعد:

@app.route('/')
def root():
    'main application (GET) handler'
    # check for (hour-)cached visits
    ip_addr, usr_agt = request.remote_addr, request.user_agent
    visitor = '{}: {}'.format(ip_addr, usr_agt)
    visits = memcache.get('visits')

    # register visit & run DB query if cache empty or new visitor
    if not visits or visits[0]['visitor'] != visitor:
        store_visit(ip_addr, usr_agt)
        visits = list(fetch_visits(10))
        memcache.set('visits', visits, HOUR)  # set() not add()

    return render_template('index.html', visits=visits)

في ما يلي عرض تصويري للتغييرات التي تمّ إجراؤها:

b1242503602f7bf0.png

بذلك يتم إنهاء جميع التغييرات اللازمة لإضافة استخدام App Engine memcache إلى نموذج تطبيق الوحدة 1. دعونا ننشئ هذا التطبيق وننشره لكي يعمل!

6- الملخّص/تنظيف البيانات

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

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

أعِد نشر تطبيقك باستخدام "gcloud app deploy"، وتأكَّد من أنّه يعمل. يجب أن تتطابق الرمز الآن مع ما هو موجود في FINISH، مجلد الوحدة 12. يجب أن تكون النتيجة مماثلة لتطبيق الوحدة 1 الذي نشرته سابقًا:

a7a9d2b80d706a2b.png

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

تهانينا على إكمال الدرس التطبيقي حول الترميز الخاص بالوحدة 12 لإضافة استخدام خدمة App Engine memcache إلى نموذج التطبيق. يمكنك الآن نقل تطبيق Python 2 هذا إلى Python 3 في خطوة المكافأة.

تَنظيم

بنود عامة

إذا كنت قد انتهيت الآن، ننصحك بإيقاف تطبيق 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 Memcache بنوعين مختلفتين، لكل منها هيكل تسعير خاص بها، لذلك عليك تتبع هذا الاستخدام من حيث ارتباطه بالفوترة.
  • يتم تقديم خدمة مخزن بيانات App Engine من خلال Cloud Datastore (Cloud Firestore في وضع "مخزن البيانات") التي توفّر أيضًا فئة مجانية. يمكنك الاطّلاع على صفحة الأسعار لمزيد من المعلومات.

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

تتناول الوحدة 13 عملية النقل المنطقي التالية التي يجب مراعاتها في الوحدة 13، والتي توضح للمطوّرين كيفية نقل البيانات من خدمة App Engine memcache إلى Cloud Memorystore. جميع عمليات النقل هذه اختيارية ومتاحة للمستخدمين الذين يريدون اتخاذ خطوات مختلفة لتحديث تطبيقاتهم. إنّ خدمة Cloud Memorystore هي ترقية مهمة لـ memcache في App Engine لأسباب عديدة:

  • لا تكون خدمة Cloud Memorystore بدون خادم. وهذا يعني أنه يجب تخصيص خادم لذاكرة التخزين المؤقت. لا يتوفّر في Cloud Memorystore فئة مجانية. يمكن أن يكون لهذين العاملين تأثير كبير على التكلفة.
  • تتوافق خدمة Cloud Memorystore مع آليات تخزين أساسية مختلفة (محركات التخزين المؤقت) وRedis وMemcached.
  • تضم خدمة Cloud Memorystore (في Redis) مجموعة ميزات أكثر تفصيلاً وأكثر تفصيلاً من App Engine Memcache.
  • لاستخدام Cloud Memorystore، يجب إعداد خادم Cloud Memorystore، وإضافته إلى شبكة Google Cloud VPC، ثم جعل تطبيق App Engine يستخدم تلك الشبكة للاتصال بخادم Memorystore.

إذا لم تكن بحاجة إلى جميع الميزات المتوفّرة في Cloud Memorystore أو إذا كنت قلقًا بشأن تأثيرها على التكلفة، يمكنك مواصلة استخدام App Engine Memcache.

بالإضافة إلى الوحدة 13، هناك عدد كبير من عمليات نقل البيانات الأخرى المحتملة، مثل Cloud NDB وCloud Datastore أو Cloud Tasks. هناك أيضًا عمليات نقل على مستوى منتجات متعددة إلى Cloud Run وCloud Functions. ويمكنك العثور عليها كلّها في مستودع نقل البيانات.

تتوفر خطوة تالية أخرى محتملة وهي الانتقال إلى بايثون 3، وقد تم تناولها في القسم التالي كخطوة اختيارية.

7. المكافأة: النقل إلى Python 3

نظرة عامة

يضم هذا القسم محتوى إضافي اختياري ينقل تطبيق الوحدة 12 الذي انتهينا منه للتو إلى بايثون 3. نبدأ بالإعداد متبوعًا بالتطبيق.

تبسيط app.yaml

إحدى مزايا بيئة تشغيل Python 3 هي أنّه يمكن تبسيط app.yaml بشكل كبير.

قبل:

في ما يلي ما ورد في app.yaml في ختام الوحدة 12:

runtime: python27
threadsafe: yes
api_version: 1

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

يجب تغيير جميع معالِجات المسارات في app.yaml إلى auto لأنّ وقت تشغيل Python 3 يتطلّب من أطر عمل الويب تنفيذ التوجيه الخاص بها. في حال عدم عرض أي ملفات ثابتة، يمكن للمستخدمين إزالة قسم "handlers:" بالكامل مباشرةً. بالإضافة إلى ذلك، تم إيقاف كل من threadsafe وapi_version نهائيًا.

بعد:

مع التغييرات المطلوبة التي تم وصفها للتو، هذا هو app.yaml البديل للغة Python 3:

runtime: python39
app_engine_apis: true

السطر الوحيد الذي يحتاج إلى توضيح هو app_engine_apis: true. عندما أصبحت خدمات App Engine القديمة متاحة لبيئات تشغيل الجيل الثاني في عام 2021، كانت بعض بيئات التشغيل، بما في ذلك Python 3، تتطلب بدء تشغيل إضافي للوصول إلى واجهات برمجة التطبيقات هذه، مثل ndb وtaskqueue وmemcache. ويخدم هذا السطر في التهيئة هذا الغرض.

تعديل المتطلبات.txt

يلزم إجراء تشغيل آخر لواجهات برمجة التطبيقات الأصلية في requirements.txt: يجب أن يتضمن الوصول إلى حزمة تطوير البرامج (SDK) الجديدة لـ App Engine.

قبل:

في ما يلي ما ورد في app.yaml في ختام الوحدة 12:

flask

بعد:

ما عليك سوى إضافة App Engine Python SDK، من المفترض أن يكون لديك ما يلي:

flask
appengine-python-standard

احذف appengine_config.py وlib

الجيل التالي من بيئات تشغيل App Engine يجدد استخدام الحزمة التابعة لجهة خارجية:

  • المكتبات المدمجة هي المكتبات التي تحققت منها Google وتم توفيرها على خوادم App Engine، ويرجع ذلك على الأرجح إلى احتواءها على رمز C/C++ لا يُسمَح للمطوّرين بنشره على السحابة الإلكترونية، ولم تعُد هذه المكتبات متاحة في بيئات تشغيل الجيل الثاني.
  • لم تعُد هناك حاجة إلى نسخ المكتبات غير المضمّنة (تُسمّى أحيانًا "التوريد" أو "التجميع الذاتي") في بيئات تشغيل الجيل الثاني. وبدلاً من ذلك، يجب إدراجها في requirements.txt حيث يثبّتها نظام الإصدار تلقائيًا نيابةً عنك في وقت النشر.

ونتيجةً لهذه التغييرات التي طرأت على إدارة الحِزم التابعة لجهات خارجية، لا حاجة إلى ملف appengine_config.py أو مجلد lib، لذا يُرجى حذفهما. في بيئات تشغيل الجيل الثاني، يثبِّت App Engine تلقائيًا حِزم الجهات الخارجية المدرَجة في requirements.txt. التلخيص:

  1. عدم توفّر مكتبات تابعة لجهات خارجية مجمّعة بشكل ذاتي أو منسوخة إدراجهم في requirements.txt
  2. لا يتم حفظ pip install في مجلد "lib"، ما يعني أنّه ما مِن مدة للمجلد "lib".
  3. عدم توفّر مكتبات تابعة لجهات خارجية مضمّنة (بدون قسم libraries) في app.yaml إدراجهم في requirements.txt
  4. ما مِن مكتبات تابعة لجهات خارجية يمكن الرجوع إليها من تطبيقك، ما يعني عدم توفُّر ملف appengine_config.py.

الشرط الوحيد للمطوّر هو إدراج جميع مكتبات الجهات الخارجية المطلوبة في requirements.txt.

تحديث التطبيق لاستخدام App Engine SDK

كما ذكرنا أعلاه، تتطلب تطبيقات Python 3 بعض التعديلات للوصول إلى خدمات App Engine المجمّعة:

  1. حزمة SDK لـ App Engine (في requirements.txt)
  2. تفعيل حزمة تطوير البرامج (SDK) لـ App Engine (في app.yaml)
  3. التفاف كائن WSGI (باللون main.py)

تم إكمال أول عملية زوجية أعلاه، لذا آخر متطلب هو تحديث main.py.

قبل:

وفي ما يلي لغة Python 2 main.py في ختام الوحدة 12:

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

app = Flask(__name__)
HOUR = 3600

بعد:

بالنسبة إلى منفذ Python 3، عليك استيراد حزمة تطوير البرامج (SDK) والتفاف كائن تطبيق Flask معها (برنامج تضمين حزمة تطوير البرامج (SDK)، ما ينتج عنه ما يلي:

from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb

app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600

يحتاج المطوّرون إلى إجراء هذه التغييرات على تطبيقات Python عند النقل من 2.x إلى 3.x للوصول إلى الخدمات المُجمّعة. في حال عدم استخدام Flask، يمكنك أيضًا الاطّلاع على نماذج Django وPyramid في المستندات. إذا لم يكن رمز Python 2 تطبيق ويب، يكفي تضمين حزمة SDK عند النقل إلى Python 3. تم إنشاء رمز التطبيق في الأصل للعمل باستخدام بايثون 2 و3، ولذلك لا يلزم إجراء أي تغييرات إضافية على التوافق.

نشر التطبيق

بعد إكمال التغييرات أعلاه، يمكنك نشر نموذج التطبيق المحدَّث. (ليست هناك مشكلة عند نشر إصدار Python 3 من تطبيقك على إصدار Python 2 أصلي في مشروع Google Cloud Platform نفسه). يجب أن يظل سلوك التطبيق كما هو. إذا أردت مقارنة تطبيقك المعدَّل بتطبيقنا، يُرجى الاطّلاع على مجلد الوحدة 12 ب في مستودع نقل البيانات. للاطّلاع على مزيد من المعلومات حول دعم خدمات App Engine المجمّعة في أحدث بيئات التشغيل مثل Python 3، يمكنك الاطّلاع على الإعلان عن إطلاق الميزات بالإضافة إلى الدرس التطبيقي حول الترميز Module 17.

تهانينا على الانتهاء من الخطوة الإضافية في الوحدة 12! راجِع أيضًا المستندات المتعلقة بإعداد ملفات الإعداد لوقت تشغيل Python 3. راجع قسم الملخص/التنظيف أعلاه لمعرفة الخطوات التالية والتنظيف.

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

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

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

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

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

يمكن العثور على روابط لمجلدات repo للوحدة 2 (START) والوحدة 12 (FINISH) في الجدول أدناه. يمكن أيضًا الوصول إليها من المستودع الخاص بجميع عمليات نقل البيانات التطبيقية حول الترميز في App Engine، والتي يمكنك استنساخ ملف ZIP أو تنزيله.

Codelab

Python 2

Python 3

الوحدة 1

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

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

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

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

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

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

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

App Engine

Cloud Memorystore وCloud Datastore

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

الفيديوهات

الترخيص

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