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

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

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

  • تقليل وقت وحدة المعالجة المركزية المستغرق في إنشاء اتصالات جديدة عند كل استدعاء دالة.
  • تقليل احتمالية نفاد الاتصال أو حصص DNS .

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

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

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

  • HTTP/S
  • واجهات برمجة تطبيقات جوجل

طلبات 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();
});

بايثون

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 .

الوصول إلى واجهات برمجة تطبيقات جوجل

يستخدم المثال أدناه Cloud Pub/Sub ، ولكن هذا الأسلوب يعمل أيضًا مع مكتبات العملاء الأخرى - على سبيل المثال، Cloud Natural Language أو Cloud Spanner . لاحظ أن تحسينات الأداء قد تعتمد على التنفيذ الحالي لمكتبات عملاء معينة.

يؤدي إنشاء كائن عميل Pub/Sub إلى اتصال واحد واستعلامي DNS لكل استدعاء. لتجنب الاتصالات غير الضرورية واستعلامات DNS، قم بإنشاء كائن عميل 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');
        }
    });
});

بايثون

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. وفي أوقات التشغيل اللاحقة، تأكد من تحديده عند نشر الوظيفة. راجع تكوين متغيرات البيئة .

تحميل اختبار وظيفتك

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

$ artillery quick -d 300 -r 30 URL

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

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

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