নেটওয়ার্কিং অপ্টিমাইজ করা

Cloud Functions-এর সরলতা আপনাকে দ্রুত কোড ডেভেলপ করতে এবং এটি একটি সার্ভারলেস পরিবেশে চালাতে দেয়। মাঝারি স্কেলে, ফাংশন চালানোর খরচ কম, এবং আপনার কোড অপ্টিমাইজ করাকে উচ্চ অগ্রাধিকার বলে মনে নাও হতে পারে। তবে, আপনার ডেপ্লয়মেন্ট স্কেল আপ করার সাথে সাথে, আপনার কোড অপ্টিমাইজ করা ক্রমশ গুরুত্বপূর্ণ হয়ে ওঠে।

আপনার ফাংশনের জন্য কীভাবে নেটওয়ার্কিং অপ্টিমাইজ করবেন তা এই ডকুমেন্টে বর্ণনা করা হয়েছে। নেটওয়ার্কিং অপ্টিমাইজ করার কিছু সুবিধা নিচে উল্লেখ করা হল:

  • প্রতিটি ফাংশন কলে নতুন আউটবাউন্ড কানেকশন তৈরি করতে সিপিইউ টাইম কমান।
  • কানেকশন বা DNS কোটা শেষ হয়ে যাওয়ার সম্ভাবনা কমান।

একটানা কানেকশন বজায় রাখা হচ্ছে

এই বিভাগে, কোনও ফাংশনে কীভাবে পারসিস্টেন্ট কানেকশন বজায় রাখতে হয় তার উদাহরণ দেওয়া হয়েছে। এটি না করলে, কানেকশন কোটা দ্রুত শেষ হয়ে যেতে পারে।

এই বিভাগে নিম্নলিখিত পরিস্থিতিগুলি কভার করা হয়েছে:

  • 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) নেয় এবং উত্তরের টেক্সট বা এমন কোনও ভ্যালুর সেট ফেরত দেয় যা make_response ব্যবহার করে Response অবজেক্টে পরিবর্তন করা যায়।

Google API অ্যাক্সেস করা

নিচের উদাহরণে Cloud Pub/Sub ব্যবহার করা হয়েছে, তবে এই পদ্ধতি অন্যান্য ক্লায়েন্ট লাইব্রেরির ক্ষেত্রেও কাজ করে—যেমন, Cloud Natural Language অথবা Cloud Spanner। মনে রাখবেন যে পারফর্ম্যান্সের উন্নতি নির্দিষ্ট ক্লায়েন্ট লাইব্রেরির বর্তমান প্রয়োগের উপর নির্ভর করতে পারে।

Pub/Sub ক্লায়েন্ট অবজেক্ট তৈরি করলে, প্রতিবার ইনভোকেশনের জন্য একটি কানেকশন ও দুটি ডিএনএস কোয়েরি তৈরি হয়। অপ্রয়োজনীয় কানেকশন ও 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');
        }
    });
});

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) নেয় এবং রেসপন্স টেক্সট বা যেকোনও ভ্যালুর সেট ফেরত দেয় যা make_response ব্যবহার করে Response অবজেক্টে পরিণত করা যেতে পারে।

Python 3.7 রানটাইমে GCP_PROJECT এনভায়রনমেন্ট ভেরিয়েবল অটোমেটিক সেট হয়ে যায়। পরবর্তী রানটাইমে, ফাংশন ডেপ্লয়মেন্টে এটি উল্লেখ করতে ভুলবেন না। এনভায়রনমেন্ট ভেরিয়েবল কনফিগার করুন দেখুন।

আউটবাউন্ড কানেকশন

আউটবাউন্ড অনুরোধের টাইমআউট

আপনার ফাংশন থেকে VPC নেটওয়ার্কে অনুরোধ পাঠানোর ক্ষেত্রে ১০ মিনিট কোনও অ্যাক্টিভিটি না হলে টাইমআউট হয়ে যায়। আপনার ফাংশন থেকে ইন্টারনেটে অনুরোধের জন্য, ২০ মিনিট নিষ্ক্রিয় থাকার পরে টাইমআউট হয়।

আউটবাউন্ড কানেকশন রিসেট

আপনার ফাংশন থেকে VPC নেটওয়ার্ক এবং ইন্টারনেট, দুটিতেই কানেকশন স্ট্রিম মাঝে মাঝে বন্ধ হয়ে যেতে পারে এবং অন্তর্নিহিত ইনফ্রাস্ট্রাকচার রিস্টার্ট বা আপডেট করা হলে তা পরিবর্তন করা হতে পারে। আপনার অ্যাপ্লিকেশন যদি দীর্ঘস্থায়ী কানেকশন আবার ব্যবহার করে, তাহলে আমরা সাজেস্ট করি যে আপনি অ্যাপ্লিকেশনটি এমনভাবে কনফিগার করুন যাতে এটি কানেকশন আবার স্থাপন করে। এটি করলে, ডেড কানেকশন আবার ব্যবহার করা এড়ানো যাবে।

আপনার ফাংশনের লোড-টেস্টিং করা

আপনার ফাংশন গড়ে কতগুলি কানেকশন পারফর্ম করে তা পরিমাপ করতে, এটি একটি HTTP ফাংশন হিসাবে ডিপ্লয় করুন এবং নির্দিষ্ট QPS-এ এটি চালু করতে একটি পারফর্ম্যান্স-টেস্টিং ফ্রেমওয়ার্ক ব্যবহার করুন। একটি সম্ভাব্য বিকল্প হল Artillery, যা আপনি একটি লাইন দিয়ে চালু করতে পারেন:

$ artillery quick -d 300 -r 30 URL

এই কমান্ড ৩০০ সেকেন্ডের জন্য ৩০ QPS-এ প্রদত্ত URL নিয়ে আসে।

টেস্ট করার পরে, Google Cloud কনসোলের Cloud Functions API কোটা পৃষ্ঠায় আপনার কানেকশন কোটার ব্যবহার চেক করুন। ব্যবহার যদি ক্রমাগত ৩০ (বা এর গুণিতক) এর কাছাকাছি হয়, তাহলে আপনি প্রতিটি ইনভোকেশনে একটি (বা একাধিক) কানেকশন স্থাপন করছেন। কোড অপ্টিমাইজ করার পরে, আপনি দেখতে পাবেন যে টেস্টের শুরুতে কয়েকটি (১০-৩০) কানেকশন তৈরি হয়েছে।

এছাড়াও, আপনি একই পৃষ্ঠায় সিপিইউ কোটা প্লটে সিপিইউ অপ্টিমাইজেশনের আগে এবং পরে সিপিইউ খরচ তুলনা করতে পারেন।