يصف هذا المستند أفضل الممارسات لتصميم وتنفيذ واختبار ونشر وظائف السحابة.
الصواب
يصف هذا القسم أفضل الممارسات العامة لتصميم وتنفيذ وظائف السحابة.
اكتب وظائف عاطلة
يجب أن تنتج وظائفك نفس النتيجة حتى لو تم استدعاؤها عدة مرات. يتيح لك هذا إعادة محاولة استدعاء إذا فشل الاستدعاء السابق جزئيًا خلال التعليمات البرمجية الخاصة بك. لمزيد من المعلومات ، راجع إعادة محاولة الوظائف التي تستند إلى الأحداث .
لا تبدأ أنشطة الخلفية
نشاط الخلفية هو أي شيء يحدث بعد انتهاء وظيفتك. ينتهي استدعاء الدالة بمجرد إرجاع الدالة أو تشير إلى اكتمالها ، مثل استدعاء وسيطة callback
في وظائف Node.js المستندة إلى الأحداث. أي رمز يتم تشغيله بعد الإنهاء الجميل لا يمكنه الوصول إلى وحدة المعالجة المركزية ولن يحرز أي تقدم.
بالإضافة إلى ذلك ، عند تنفيذ استدعاء لاحق في نفس البيئة ، يتم استئناف نشاط الخلفية لديك ، مما يتداخل مع الاستدعاء الجديد. قد يؤدي هذا إلى سلوك غير متوقع وأخطاء يصعب تشخيصها. عادةً ما يؤدي الوصول إلى الشبكة بعد انتهاء الوظيفة إلى إعادة تعيين الاتصالات (رمز خطأ ECONNRESET
).
غالبًا ما يمكن اكتشاف نشاط الخلفية في السجلات من الاستدعاءات الفردية ، من خلال العثور على أي شيء يتم تسجيله بعد السطر الذي يشير إلى انتهاء الاستدعاء. يمكن أحيانًا دفن نشاط الخلفية بشكل أعمق في الكود ، خاصةً عند وجود عمليات غير متزامنة مثل عمليات الاسترجاعات أو المؤقتات. راجع التعليمات البرمجية الخاصة بك للتأكد من انتهاء جميع العمليات غير المتزامنة قبل إنهاء الوظيفة.
احذف الملفات المؤقتة دائمًا
تخزين القرص المحلي في الدليل المؤقت هو نظام ملفات في الذاكرة. الملفات التي تكتبها تستهلك الذاكرة المتاحة لوظيفتك ، وفي بعض الأحيان تستمر بين الدعوات. قد يؤدي الفشل في حذف هذه الملفات بشكل صريح في النهاية إلى حدوث خطأ نفاد الذاكرة وبدء بارد لاحق.
يمكنك رؤية الذاكرة المستخدمة بواسطة وظيفة فردية عن طريق تحديدها في قائمة الوظائف في وحدة تحكم GCP واختيار مخطط استخدام الذاكرة .
لا تحاول الكتابة خارج الدليل المؤقت ، وتأكد من استخدام أساليب مستقلة عن النظام الأساسي / نظام التشغيل لإنشاء مسارات الملفات.
يمكنك تقليل متطلبات الذاكرة عند معالجة الملفات الكبيرة باستخدام التسلسل. على سبيل المثال ، يمكنك معالجة ملف على Cloud Storage عن طريق إنشاء تدفق للقراءة ، وتمريره عبر عملية قائمة على التدفق ، وكتابة دفق الإخراج مباشرة إلى Cloud Storage.
أدوات
يوفر هذا القسم إرشادات حول كيفية استخدام الأدوات لتنفيذ وظائف السحابة واختبارها والتفاعل معها.
التنمية المحلية
يستغرق نشر الوظيفة بعض الوقت ، لذلك غالبًا ما يكون اختبار رمز وظيفتك محليًا أسرع.
يمكن لمطوري Firebase استخدام Firebase CLI Cloud Functions Emulator .استخدم Sendgrid لإرسال رسائل البريد الإلكتروني
لا تسمح وظائف السحابة بالاتصالات الصادرة على المنفذ 25 ، لذلك لا يمكنك إجراء اتصالات غير آمنة بخادم SMTP. الطريقة الموصى بها لإرسال رسائل البريد الإلكتروني هي استخدام SendGrid . يمكنك العثور على خيارات أخرى لإرسال بريد إلكتروني في إرسال بريد إلكتروني من برنامج تعليمي مثيل لـ Google Compute Engine.
أداء
يصف هذا القسم أفضل الممارسات لتحسين الأداء.
استخدم التبعيات بحكمة
نظرًا لأن الوظائف عديمة الحالة ، غالبًا ما تتم تهيئة بيئة التنفيذ من نقطة الصفر (أثناء ما يُعرف بالبداية الباردة ). عند حدوث بداية باردة ، يتم تقييم السياق العام للوظيفة.
إذا كانت وظائفك تستورد الوحدات النمطية ، فيمكن أن يضيف وقت تحميل هذه الوحدات إلى زمن انتقال الاستدعاء أثناء بدء التشغيل البارد. يمكنك تقليل وقت الاستجابة هذا ، بالإضافة إلى الوقت اللازم لنشر وظيفتك ، عن طريق تحميل التبعيات بشكل صحيح وعدم تحميل التبعيات التي لا تستخدمها وظيفتك.
استخدم المتغيرات العامة لإعادة استخدام الكائنات في الدعوات المستقبلية
ليس هناك ما يضمن الحفاظ على حالة وظيفة السحابة للاستدعاءات المستقبلية. ومع ذلك ، غالبًا ما تقوم وظائف السحابة بإعادة تدوير بيئة التنفيذ لاستدعاء سابق. إذا قمت بتعريف متغير في النطاق العام ، فيمكن إعادة استخدام قيمته في الاستدعاءات اللاحقة دون الحاجة إلى إعادة الحساب.
بهذه الطريقة يمكنك تخزين العناصر التي قد تكون مكلفة لإعادة إنشائها في كل استدعاء دالة. قد يؤدي نقل هذه الكائنات من الجسم الوظيفي إلى النطاق العالمي إلى تحسينات كبيرة في الأداء. ينشئ المثال التالي كائنًا ثقيلًا مرة واحدة فقط لكل مثيل دالة ، ويشاركه عبر جميع استدعاءات الوظيفة التي تصل إلى المثيل المحدد:
console.log('Global scope');
const perInstance = heavyComputation();
const functions = require('firebase-functions');
exports.function = functions.https.onRequest((req, res) => {
console.log('Function invocation');
const perFunction = lightweightComputation();
res.send(`Per instance: ${perInstance}, per function: ${perFunction}`);
});
من المهم بشكل خاص تخزين اتصالات الشبكة ومراجع المكتبات وكائنات عميل API في النطاق العالمي. راجع تحسين الشبكات للحصول على أمثلة.
قم بإجراء التهيئة البطيئة للمتغيرات العالمية
إذا قمت بتهيئة المتغيرات في النطاق العام ، فسيتم دائمًا تنفيذ كود التهيئة من خلال استدعاء البدء البارد ، مما يزيد من زمن انتقال وظيفتك. في بعض الحالات ، يتسبب هذا في انقضاء مهلات متقطعة للخدمات التي يتم استدعاؤها إذا لم يتم التعامل معها بشكل مناسب في مجموعة try
/ catch
. إذا لم يتم استخدام بعض الكائنات في جميع مسارات التعليمات البرمجية ، ففكر في تهيئتها ببطء عند الطلب:
const functions = require('firebase-functions');
let myCostlyVariable;
exports.function = functions.https.onRequest((req, res) => {
doUsualWork();
if(unlikelyCondition()){
myCostlyVariable = myCostlyVariable || buildCostlyVariable();
}
res.status(200).send('OK');
});
هذا مهم بشكل خاص إذا حددت عدة وظائف في ملف واحد ، وتستخدم وظائف مختلفة متغيرات مختلفة. ما لم تستخدم التهيئة البطيئة ، فقد تهدر الموارد على المتغيرات التي تمت تهيئتها ولكن لم يتم استخدامها مطلقًا.
تقليل البدايات الباردة عن طريق تعيين الحد الأدنى لعدد الحالات
بشكل افتراضي ، تقوم وظائف السحابة بقياس عدد الطبعات بناءً على عدد الطلبات الواردة. يمكنك تغيير هذا السلوك الافتراضي عن طريق تعيين الحد الأدنى لعدد المثيلات التي يجب أن تظل وظائف السحابة جاهزة لها لخدمة الطلبات. يؤدي تعيين حد أدنى لعدد المثيلات إلى تقليل عمليات البدء الباردة لتطبيقك. نوصي بتعيين الحد الأدنى لعدد المثيلات إذا كان تطبيقك حساسًا لوقت الاستجابة.
راجع سلوك التحكم في القياس لمزيد من المعلومات حول خيارات وقت التشغيل هذه.مصادر إضافية
اكتشف المزيد حول تحسين الأداء في وقت التشغيل البارد للفيديو "Google Cloud Performance Atlas".