नेटवर्किंग को ऑप्टिमाइज़ किया जा रहा है

Cloud Functions की मदद से, कोड को आसानी से और तेज़ी से डेवलप किया जा सकता है. साथ ही, इसे सर्वरलेस एनवायरमेंट में चलाया जा सकता है. मॉडरेट स्केल पर, फ़ंक्शन चलाने की लागत कम होती है. इसलिए, कोड को ऑप्टिमाइज़ करना ज़रूरी नहीं होता. हालांकि, डिप्लॉयमेंट का स्केल बढ़ने पर, कोड को ऑप्टिमाइज़ करना ज़रूरी हो जाता है.

इस दस्तावेज़ में, फ़ंक्शन के लिए नेटवर्क को ऑप्टिमाइज़ करने का तरीका बताया गया है. नेटवर्क को ऑप्टिमाइज़ करने के कुछ फ़ायदे यहां दिए गए हैं:

  • हर फ़ंक्शन कॉल पर, नए आउटबाउंड कनेक्शन बनाने में लगने वाले सीपीयू के समय को कम करना.
  • कनेक्शन या डीएनएस कोटा खत्म होने की संभावना को कम करना.

परसिस्टेंट कनेक्शन बनाए रखना

इस सेक्शन में, किसी फ़ंक्शन में परसिस्टेंट कनेक्शन बनाए रखने के तरीके के उदाहरण दिए गए हैं. ऐसा न करने पर, कनेक्शन कोटा जल्दी खत्म हो सकता है.

इस सेक्शन में, ये स्थितियां शामिल हैं:

  • एचटीटीपी या एचटीटीपीएस
  • Google API

एचटीटीपी या एचटीटीपीएस अनुरोध

नीचे दिया गया ऑप्टिमाइज़ किया गया कोड स्निपेट दिखाता है कि हर फ़ंक्शन को लागू करने पर नया कनेक्शन बनाने के बजाय, परसिस्टेंट कनेक्शन कैसे बनाए रखें:

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!")
    

यह एचटीटीपी फ़ंक्शन, एचटीटीपी अनुरोध करने के लिए कनेक्शन पूल का इस्तेमाल करता है. यह एक अनुरोध ऑब्जेक्ट (flask.Request) लेता है और रिस्पॉन्स टेक्स्ट या वैल्यू का कोई भी ऐसा सेट दिखाता है जिसे Response ऑब्जेक्ट में बदला जा सकता है make_response.

Google API ऐक्सेस करना

यहां दिए गए उदाहरण में, Cloud Pub/Sub का इस्तेमाल किया गया है. हालांकि, यह तरीका अन्य क्लाइंट लाइब्रेरी के लिए भी काम करता है. जैसे, Cloud Natural 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")
    

यह एचटीटीपी फ़ंक्शन, कैश की गई क्लाइंट लाइब्रेरी इंस्टेंस का इस्तेमाल करता है, ताकि हर फ़ंक्शन को लागू करने के लिए ज़रूरी कनेक्शन की संख्या कम की जा सके. यह एक अनुरोध ऑब्जेक्ट (flask.Request) लेता है और रिस्पॉन्स टेक्स्ट या वैल्यू का कोई भी ऐसा सेट दिखाता है जिसे Response ऑब्जेक्ट में बदला जा सकता है make_response का इस्तेमाल करके.

GCP_PROJECT एनवायरमेंट वैरिएबल, Python 3.7 रनटाइम में अपने-आप सेट हो जाता है. बाद के रनटाइम में, पक्का करें कि इसे फ़ंक्शन डिप्लॉयमेंट पर तय किया गया हो. एनवायरमेंट वैरिएबल कॉन्फ़िगर करना लेख पढ़ें.

आउटबाउंड कनेक्शन

आउटबाउंड अनुरोधों के लिए टाइम आउट

आपके फ़ंक्शन से वीपीसी नेटवर्क पर किए जाने वाले अनुरोधों के लिए, 10 मिनट तक कोई गतिविधि न होने पर टाइम आउट हो जाता है. आपके फ़ंक्शन से इंटरनेट पर किए जाने वाले अनुरोधों के लिए, 20 मिनट तक कोई गतिविधि न होने पर टाइम आउट हो जाता है.

आउटबाउंड कनेक्शन रीसेट करना

बुनियादी इन्फ़्रास्ट्रक्चर को रीस्टार्ट या अपडेट करने पर, आपके फ़ंक्शन से दोनों वीपीसी नेटवर्क और इंटरनेट पर कनेक्शन स्ट्रीम कभी-कभी खत्म हो सकती हैं और उन्हें बदला जा सकता है. अगर आपका ऐप्लिकेशन, लंबे समय तक चलने वाले कनेक्शन का फिर से इस्तेमाल करता है, तो हमारा सुझाव है कि आप अपने ऐप्लिकेशन को इस तरह कॉन्फ़िगर करें कि वह कनेक्शन को फिर से बनाए, ताकि बंद हो चुके कनेक्शन का फिर से इस्तेमाल न हो.

अपने फ़ंक्शन का लोड टेस्ट करना

यह मेज़र करने के लिए कि आपका फ़ंक्शन औसतन कितने कनेक्शन बनाता है, इसे एचटीटीपी फ़ंक्शन के तौर पर डिप्लॉय करें. साथ ही, इसे तय क्यूपीएस पर लागू करने के लिए, परफ़ॉर्मेंस-टेस्टिंग फ़्रेमवर्क का इस्तेमाल करें. Artillery एक विकल्प है. इसे एक लाइन से लागू किया जा सकता है:

$ artillery quick -d 300 -r 30 URL

यह कमांड, दिए गए यूआरएल को 300 सेकंड के लिए 30 क्यूपीएस पर फ़ेच करता है.

टेस्ट करने के बाद, Cloud Console में Cloud Functions API कोटा पेज पर, अपने कनेक्शन कोटा के इस्तेमाल की जानकारी देखें. अगर इस्तेमाल की दर लगातार 30 (या इसके मल्टीपल) के आस-पास है, तो हर बार लागू करने पर एक (या कई) कनेक्शन बन रहे हैं. कोड को ऑप्टिमाइज़ करने के बाद, आपको टेस्ट की शुरुआत में सिर्फ़ कुछ (10-30) कनेक्शन दिखने चाहिए.

इसी पेज पर, सीपीयू कोटा प्लॉट पर ऑप्टिमाइज़ेशन से पहले और बाद की सीपीयू लागत की तुलना भी की जा सकती है.