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

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) लेता है और रिस्पॉन्स टेक्स्ट या वैल्यू का कोई ऐसा सेट दिखाता है जिसे make_response का इस्तेमाल करके 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) लेता है और रिस्पॉन्स टेक्स्ट या वैल्यू का कोई ऐसा सेट दिखाता है जिसे make_response का इस्तेमाल करके Response ऑब्जेक्ट में बदला जा सकता है.

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

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

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

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

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

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

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

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

$ artillery quick -d 300 -r 30 URL

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

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

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