تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
تتيح لك بساطة Cloud Functions تطوير الرموز البرمجية وتشغيلها بسرعة في بيئة بدون خادم. وعندما يكون عدد مرات التشغيل معتدلاً، تكون تكلفة تشغيل الدوال منخفضة، وقد لا يبدو تحسين الرمز البرمجي أولوية قصوى. ومع ذلك، كلما زاد حجم عملية النشر، أصبحت عملية تحسين الرمز البرمجي أكثر أهمية.
يوضّح هذا المستند كيفية تحسين الشبكات لوظائفك. في ما يلي بعض مزايا تحسين الشبكات:
تقليل وقت وحدة المعالجة المركزية (CPU) المستغرَق في إنشاء اتصالات صادرة جديدة عند كل استدعاء دالة
الحدّ من احتمالية استنفاد الحصص المخصّصة للاتصال أو نظام أسماء النطاقات
الحفاظ على الاتصالات المستمرة
يعرض هذا القسم أمثلة على كيفية الحفاظ على اتصالات مستمرة في دالة. وقد يؤدي عدم إجراء ذلك إلى استنفاد حصص الربط بسرعة.
يتناول هذا القسم السيناريوهات التالية:
HTTP/S
Google APIs
طلبات HTTP/S
يوضّح مقتطف الرمز المحسّن أدناه كيفية الحفاظ على الاتصالات المستمرة
بدلاً من إنشاء اتصال جديد عند كل استدعاء دالة:
Node.js
consthttp=require('http');constfunctions=require('firebase-functions');// Setting the `keepAlive` option to `true` keeps// connections open between function invocationsconstagent=newhttp.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=>{letrawData='';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
fromfirebase_functionsimporthttps_fnimportrequests# Create a global HTTP session (which provides connection pooling)session=requests.Session()@https_fn.on_request()defconnection_pooling(request):# The URL to send the request tourl="http://example.com"# Process the requestresponse=session.get(url)response.raise_for_status()returnhttps_fn.Response("Success!")
تستخدم دالة HTTP هذه مجموعة اتصالات لإجراء طلبات HTTP. تأخذ هذه الدالة كائن طلب (flask.Request) وتعرض نص الاستجابة أو أي مجموعة من القيم التي يمكن تحويلها إلى كائن Response باستخدام make_response.
الوصول إلى Google APIs
يستخدم المثال أدناه Cloud Pub/Sub، ولكن يمكن استخدام هذا الأسلوب أيضًا مع مكتبات برامج أخرى، مثل Cloud Natural Language أو Cloud Spanner. يُرجى العِلم أنّ التحسينات في الأداء قد تعتمد على التنفيذ الحالي لمكتبات عملاء معيّنة.
يؤدي إنشاء عنصر عميل Pub/Sub إلى إنشاء اتصال واحد وطلبَي بحث في نظام أسماء النطاقات (DNS) لكل عملية استدعاء. لتجنُّب عمليات الربط وطلبات نظام أسماء النطاقات غير الضرورية، أنشِئ عنصر عميل Pub/Sub في النطاق العام كما هو موضّح في المثال أدناه:
node.js
constPubSub=require('@google-cloud/pubsub');constfunctions=require('firebase-functions');constpubsub=PubSub();exports.function=functions.https.onRequest((req,res)=>{consttopic=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
importosfromfirebase_functionsimporthttps_fnfromgoogle.cloudimportpubsub_v1# from firebase_functions import https_fn# Create a global Pub/Sub client to avoid unneeded network activitypubsub=pubsub_v1.PublisherClient()@https_fn.on_request()defgcp_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 requestdata=b"Test message"pubsub.publish(topic_path,data=data)returnhttps_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 في Cloud Console. إذا كان الاستخدام يبلغ حوالي 30 (أو مضاعفاته) بشكل منتظم، يعني ذلك أنّك تنشئ اتصالاً واحدًا (أو عدة اتصالات) في كل عملية استدعاء. بعد تحسين الرمز، من المفترض أن تلاحظ حدوث بضعة اتصالات (من 10 إلى 30) في بداية الاختبار فقط.
يمكنك أيضًا مقارنة تكلفة وحدة المعالجة المركزية قبل التحسين وبعده على الرسم البياني لحصة وحدة المعالجة المركزية في الصفحة نفسها.
تاريخ التعديل الأخير: 2025-09-05 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-09-05 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["\u003cbr /\u003e\n\nThe simplicity of Cloud Functions lets you quickly develop code and run it in\na serverless environment. At moderate scale, the cost of running functions is\nlow, and optimizing your code might not seem like a high priority. As your\ndeployment scales up, however, optimizing your code becomes increasingly\nimportant.\n\nThis document describes how to optimize networking for your functions. Some of\nthe benefits of optimizing networking are as follows:\n\n- Reduce CPU time spent in establishing new outbound connections at each function call.\n- Reduce the likelihood of running out of connection or DNS [quotas](https://cloud.google.com/functions/quotas).\n\nMaintaining Persistent Connections\n\nThis section gives examples of how to maintain persistent connections in a\nfunction. Failure to do so can result in quickly exhausting connection quotas.\n\nThe following scenarios are covered in this section:\n\n- HTTP/S\n- Google APIs\n\nHTTP/S Requests\n\nThe optimized code snippet below shows how to maintain persistent connections\ninstead of creating a new connection upon every function invocation: \n\nNode.js \n\n```javascript\nconst http = require('http');\nconst functions = require('firebase-functions');\n\n// Setting the `keepAlive` option to `true` keeps\n// connections open between function invocations\nconst agent = new http.Agent({keepAlive: true});\n\nexports.function = functions.https.onRequest((request, response) =\u003e {\n req = http.request({\n host: '',\n port: 80,\n path: '',\n method: 'GET',\n agent: agent, // Holds the connection open after the first invocation\n }, res =\u003e {\n let rawData = '';\n res.setEncoding('utf8');\n res.on('data', chunk =\u003e { rawData += chunk; });\n res.on('end', () =\u003e {\n response.status(200).send(`Data: ${rawData}`);\n });\n });\n req.on('error', e =\u003e {\n response.status(500).send(`Error: ${e.message}`);\n });\n req.end();\n});\n```\n\nPython \n\n```python\nfrom firebase_functions import https_fn\nimport requests\n\n# Create a global HTTP session (which provides connection pooling)\nsession = requests.Session()\n\n@https_fn.on_request()\ndef connection_pooling(request):\n\n # The URL to send the request to\n url = \"http://example.com\"\n\n # Process the request\n response = session.get(url)\n response.raise_for_status()\n return https_fn.Response(\"Success!\")\n \n```\n\nThis HTTP function uses a connection pool to make HTTP requests. It takes a\nrequest object (`flask.Request`) and returns the response text, or any set\nof values that can be turned into a `Response` object using\n[`make_response`](https://flask.palletsprojects.com/en/3.0.x/api/#flask.make_response).\n\nAccessing Google APIs\n\nThe example below uses [Cloud\nPub/Sub](//cloud.google.com/pubsub/docs/reference/libraries), but this approach\nalso works for other client libraries---for example, [Cloud Natural\nLanguage](//cloud.google.com/natural-language/docs/reference/libraries) or\n[Cloud Spanner](//cloud.google.com/spanner/docs/reference/libraries). Note that\nperformance improvements may depend on the current implementation of particular\nclient libraries.\n\nCreating a Pub/Sub client object results in one connection and two DNS queries\nper invocation. To avoid unnecessary connections and DNS queries, create the\nPub/Sub client object in global scope as shown in the sample below: \n\nnode.js \n\n```javascript\nconst PubSub = require('@google-cloud/pubsub');\nconst functions = require('firebase-functions');\nconst pubsub = PubSub();\n\nexports.function = functions.https.onRequest((req, res) =\u003e {\n const topic = pubsub.topic('');\n\n topic.publish('Test message', err =\u003e {\n if (err) {\n res.status(500).send(`Error publishing the message: ${err}`);\n } else {\n res.status(200).send('1 message published');\n }\n });\n});\n```\n\nPython \n\n```python\nimport os\n\nfrom firebase_functions import https_fn\nfrom google.cloud import pubsub_v1\n\n# from firebase_functions import https_fn\n# Create a global Pub/Sub client to avoid unneeded network activity\npubsub = pubsub_v1.PublisherClient()\n\n@https_fn.on_request()\ndef gcp_api_call(request):\n\n project = os.getenv(\"GCP_PROJECT\")\n request_json = request.get_json()\n\n topic_name = request_json[\"topic\"]\n topic_path = pubsub.topic_path(project, topic_name)\n\n # Process the request\n data = b\"Test message\"\n pubsub.publish(topic_path, data=data)\n\n return https_fn.Response(\"1 message published\")\n \n```\n\nThis HTTP function uses a cached client library instance to reduce the\nnumber of connections required per function invocation. It takes a request\nobject (`flask.Request`) and returns the response text, or any set of values\nthat can be turned into a `Response` object using\n[`make_response`](https://flask.palletsprojects.com/en/3.0.x/api/#flask.make_response).\n\nThe `GCP_PROJECT` environment variable is set automatically in the Python\n3.7 runtime. In later runtimes, make sure to specify it on function\ndeployment. See [Configure environment\nvariables](https://cloud.google.com/run/docs/configuring/services/environment-variables).\n\nOutbound connections\n\nOutbound request timeouts\n\nThere is a timeout after 10 minutes of idle time for requests from your function\nto the VPC network. For requests from your function to the internet, there is a\ntimeout after 20 minutes of idle time.\n\nOutbound connection resets\n\nConnection streams from your function to both the [VPC\nnetwork](https://cloud.google.com/run/docs/configuring/connecting-vpc) and\ninternet can be occasionally terminated and replaced when underlying\ninfrastructure is restarted or updated. If your application reuses long-lived\nconnections, we recommend that you configure your application to re-establish\nconnections to avoid the reuse of a dead connection.\n\nLoad-testing Your Function\n\nTo measure how many connections your function performs on average, deploy\nit as a HTTP function and use a performance-testing framework to invoke it at\ncertain QPS. One possible choice is [Artillery](https://artillery.io/), which\nyou can invoke with a single line: \n\n```\n$ artillery quick -d 300 -r 30 URL\n```\n\nThis command fetches the given URL at 30 QPS for 300 seconds.\n\nAfter performing the test, check the usage of your connection quota on the [Cloud Functions API quota\npage](https://console.cloud.google.com/apis/api/cloudfunctions.googleapis.com/quotas) in Cloud\nConsole. If the usage is consistently around 30 (or its multiple), you are\nestablishing one (or several) connections in every invocation. After you\noptimize your code, you should see a few (10-30) connections occur only at the\nbeginning of the test.\n\nYou can also compare the CPU cost before and after the optimization on the CPU\nquota plot on the same page."]]