تحسين الشبكات

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

يتناول هذا المستند كيفية تحسين الربط الشبكي لأداء وظائفك. بعض فوائد تحسين الشبكات هي كما يلي:

  • يمكنك تقليل وقت استخدام وحدة المعالجة المركزية (CPU) في إنشاء اتصالات جديدة عند كل استدعاء دالة.
  • قلِّل من احتمالية نفاد الاتصال أو حصص نظام أسماء النطاقات.

الحفاظ على علاقات مستمرة

يقدم هذا القسم أمثلة على كيفية الحفاظ على الاتصالات المستمرة في إحدى الدوال. وقد يؤدي عدم الالتزام بذلك إلى استنفاد حصص الاتصال بسرعة.

يتم تناول السيناريوهات التالية في هذا القسم:

  • بروتوكول 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 Natural Language أو Cloud Spanner. لاحظ أن تحسينات الأداء قد تعتمد على التنفيذ الحالي لمكتبات عملاء معينة.

يؤدي إنشاء كائن عميل Pub/Sub إلى إجراء اتصال واحد وطلبي نظام أسماء نطاقات لكل استدعاء. لتجنب الاتصالات غير الضرورية وطلبات بحث نظام أسماء النطاقات، أنشئ كائن عميل Pub/Sub في النطاق العمومي كما هو موضح في النموذج أدناه:

عقدة.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 تلقائيًا في وقت تشغيل بايثون 3.7. في أوقات التشغيل اللاحقة، تأكَّد من تحديد القاعدة عند نشر الوظيفة. يُرجى الاطّلاع على ضبط متغيرات البيئة.

اختبار تحميل الدالة

لقياس عدد الاتصالات التي تؤديها الدالة في المتوسط، يمكنك ببساطة نشرها كدالة HTTP واستخدام إطار عمل لاختبار الأداء لاستدعاءها عند عدد QPS معين. أحد الخيارات الممكنة هو المدفعية، الذي يمكنك استدعاؤه بسطر واحد:

$ artillery quick -d 300 -r 30 URL

يجلب هذا الأمر عنوان URL المحدد بسرعة 30 QPS لمدة 300 ثانية.

بعد إجراء الاختبار، يمكنك التحقّق من استخدام حصة الاتصال على صفحة حصة واجهة برمجة التطبيقات Cloud Functions API في Cloud Console. إذا كان الاستخدام باستمرار حوالي 30 (أو عدة مرات)، فأنت تنشئ اتصالاً واحدًا (أو أكثر) في كل استدعاء. بعد تحسين التعليمة البرمجية، يُفترض أن ترى عددًا قليلاً من الاتصالات (10-30) تحدث فقط في بداية الاختبار.

يمكنك أيضًا مقارنة تكلفة وحدة المعالجة المركزية (CPU) قبل وبعد التحسين على مخطط حصّة وحدة المعالجة المركزية (CPU) على الصفحة نفسها.