تتيح لك بساطة Cloud Functions تطوير الرموز البرمجية بسرعة وتشغيلها في بيئة بدون خادم. على نطاق معتدل، تكون تكلفة تشغيل الدوالّ منخفضة، وقد لا يبدو تحسين الرمز البرمجي من الأولويات العالية. ومع زيادة عمليات النشر، يزداد تحسين الرمز أهمية.
يوضّح هذا المستند كيفية تحسين الاتصال بالشبكة لوظائفك. في ما يلي بعض مزايا تحسين الشبكة:
- يمكنك تقليل وقت وحدة المعالجة المركزية الذي تقضيه في إنشاء اتصالات خارجية جديدة عند كل طلب دالة.
- الحد من احتمالية نفاد الحصص الخاصة بالاتصال أو نظام أسماء النطاقات
الحفاظ على اتصالات دائمة
يقدّم هذا القسم أمثلة على كيفية الحفاظ على اتصالات دائمة في دالّة. وقد يؤدي عدم إجراء ذلك إلى استنفاد حصص الاتصالات بسرعة.
يتناول هذا القسم السيناريوهات التالية:
- HTTP/S
- Google APIs
طلبات HTTP/S
يوضّح المقتطف المُحسَّن للرمز البرمجي أدناه كيفية الحفاظ على اتصالات دائمة بدلاً من إنشاء اتصال جديد عند كلّ استدعاء للوظيفة:
Node.js
const http = require('http'); const functions = require('firebase-functions'); // Setting the `keepAlive` option to `true` keeps // connections open between function invocations const agent = new http.Agent({keepAlive: true}); exports.function = functions.https.onRequest((request, response) => { req = http.request({ host: '' , port: 80, path: '' , method: 'GET', agent: agent, // Holds the connection open after the first invocation }, res => { let rawData = ''; res.setEncoding('utf8'); res.on('data', chunk => { rawData += chunk; }); res.on('end', () => { response.status(200).send(`Data: ${rawData}`); }); }); req.on('error', e => { response.status(500).send(`Error: ${e.message}`); }); req.end(); });
Python
from firebase_functions import https_fn import requests # Create a global HTTP session (which provides connection pooling) session = requests.Session() @https_fn.on_request() def connection_pooling(request): # The URL to send the request to url = "http://example.com" # Process the request response = session.get(url) response.raise_for_status() return https_fn.Response("Success!")
تستخدِم دالة HTTP هذه مجموعة اتصالات لتقديم طلبات HTTP. تأخذ هذه الدالة
كائن طلب (flask.Request
) وتعرض نص الاستجابة، أو أي مجموعة
من القيم التي يمكن تحويلها إلى كائن Response
باستخدام
make_response
.
الوصول إلى Google APIs
يستخدم المثال أدناه Cloud Pub/Sub، ولكن يمكن أيضًا استخدام هذا الأسلوب مع مكتبات العملاء الأخرى، مثل Cloud Language أو Cloud Spanner. يُرجى العِلم أنّه قد تعتمد تحسينات الأداء على التنفيذ الحالي ل مكتبات العميل معيّنة.
يؤدّي إنشاء عنصر عميل Pub/Sub إلى إجراء اتصال واحد وطلبَي بحث في نظام أسماء النطاقات لكلّ طلب. لتجنُّب عمليات الاتصال غير الضرورية وطلبات البحث في نظام أسماء النطاقات، أنشئ ملف تعريف العميل Pub/Sub على مستوى عام كما هو موضّح في المثال أدناه:
node.js
const PubSub = require('@google-cloud/pubsub'); const functions = require('firebase-functions'); const pubsub = PubSub(); exports.function = functions.https.onRequest((req, res) => { const topic = pubsub.topic('' ); topic.publish('Test message', err => { if (err) { res.status(500).send(`Error publishing the message: ${err}`); } else { res.status(200).send('1 message published'); } }); });
Python
import os from firebase_functions import https_fn from google.cloud import pubsub_v1 # from firebase_functions import https_fn # Create a global Pub/Sub client to avoid unneeded network activity pubsub = pubsub_v1.PublisherClient() @https_fn.on_request() def gcp_api_call(request): project = os.getenv("GCP_PROJECT") request_json = request.get_json() topic_name = request_json["topic"] topic_path = pubsub.topic_path(project, topic_name) # Process the request data = b"Test message" pubsub.publish(topic_path, data=data) return https_fn.Response("1 message published")
تستخدِم دالة HTTP هذه مثيلًا مخزَّنًا مؤقتًا من مكتبة العميل لتقليل
عدد الاتصالات المطلوبة لكلّ عملية استدعاء للدالة. تأخذ هذه الدالة كائن طلب (flask.Request
) وتعرض نص الاستجابة أو أي مجموعة من القيم التي يمكن تحويلها إلى كائن Response
باستخدام make_response
.
يتم ضبط متغيّر البيئة GCP_PROJECT
تلقائيًا في وقت تشغيل Python
3.7. في أوقات التشغيل اللاحقة، احرص على تحديدها عند مشاركة دالة برمجية. راجِع مقالة ضبط متغيّرات
البيئة.
عمليات الربط الصادرة
مهلات الطلبات الصادرة
يتم ضبط مهلة بعد 10 دقائق من وقت التوقف عن العمل للطلبات الواردة من وظيفتك إلى شبكة VPC. بالنسبة إلى الطلبات الواردة من وظيفتك إلى الإنترنت، يتم تحديد مهلة بعد 20 دقيقة من وقت التوقف.
عمليات إعادة ضبط الاتصال الصادر
يمكن أن يتم أحيانًا إنهاء عمليات نقل البيانات من الدالة إلى كل من شبكة VPC و الإنترنت واستبدالها عند إعادة تشغيل البنية الأساسية أو تعديلها. إذا كان تطبيقك يعيد استخدام اتصالات دائمة، ننصحك بضبط تطبيقك لإعادة إنشاء اتصالات لتجنُّب إعادة استخدام اتصال غير نشط.
اختبار التحميل لوظيفتك
لقياس عدد عمليات الربط التي تُجريها الدالة في المتوسّط، يمكنك نشرها كدالة HTTP واستخدام إطار عمل لاختبار الأداء لتشغيلها عند عدد معيّن من طلبات البيانات في الثانية. أحد الخيارات المحتملة هو Artillery، والذي يمكنك استدعاؤه بسطر واحد:
$ artillery quick -d 300 -r 30 URL
يُستخدَم هذا الأمر لاسترداد عنوان URL المحدّد بمعدّل 30 طلب في الثانية لمدة 300 ثانية.
بعد إجراء الاختبار، تحقَّق من استخدام حصة الاتّصال في صفحة حصة Cloud Functions API في وحدة تحكّم Cloud. إذا كان الاستخدام ثابتًا عند 30 عملية تقريبًا (أو مضاعفاتها)، يعني ذلك أنّك تُجري عملية اتصال واحدة (أو عدة عمليات) في كلّ عملية استدعاء. بعد تحسين الرمز، من المفترض أن تلاحظ حدوث عدد قليل من عمليات الربط (من 10 إلى 30) في بداية الاختبار فقط.
يمكنك أيضًا مقارنة تكلفة وحدة المعالجة المركزية قبل التحسين وبعده في الرسم البياني لحصة وحدة المعالجة المركزية في الصفحة نفسها.