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

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

এই নথিটি বর্ণনা করে কিভাবে আপনার ফাংশনের জন্য নেটওয়ার্কিং অপ্টিমাইজ করা যায়। নেটওয়ার্কিং অপ্টিমাইজ করার কিছু সুবিধা নিম্নরূপ:

  • প্রতিটি ফাংশন কলে নতুন সংযোগ স্থাপনে ব্যয় করা CPU সময় হ্রাস করুন।
  • সংযোগ বা DNS কোটা ফুরিয়ে যাওয়ার সম্ভাবনা কমিয়ে দিন।

অবিরাম সংযোগ বজায় রাখা

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

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

  • HTTP/S
  • Google API

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

Google API অ্যাক্সেস করা হচ্ছে

নীচের উদাহরণটি Cloud Pub/Sub ব্যবহার করে, কিন্তু এই পদ্ধতিটি অন্যান্য ক্লায়েন্ট লাইব্রেরির জন্যও কাজ করে—উদাহরণস্বরূপ, ক্লাউড ন্যাচারাল ল্যাঙ্গুয়েজ বা ক্লাউড স্প্যানার । উল্লেখ্য যে কর্মক্ষমতা উন্নতি নির্দিষ্ট ক্লায়েন্ট লাইব্রেরির বর্তমান বাস্তবায়নের উপর নির্ভর করতে পারে।

একটি পাব/সাব ক্লায়েন্ট অবজেক্ট তৈরি করার ফলে প্রতি আহ্বানে একটি সংযোগ এবং দুটি ডিএনএস প্রশ্ন পাওয়া যায়। অপ্রয়োজনীয় সংযোগ এবং DNS প্রশ্নগুলি এড়াতে, নীচের নমুনায় দেখানো হিসাবে গ্লোবাল স্কোপে পাব/সাব ক্লায়েন্ট অবজেক্ট তৈরি করুন:

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

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

আপনার ফাংশন লোড পরীক্ষা

আপনার ফাংশন গড়ে কতগুলি সংযোগ সঞ্চালন করে তা পরিমাপ করতে, এটিকে একটি HTTP ফাংশন হিসাবে স্থাপন করুন এবং নির্দিষ্ট QPS-এ এটি চালু করতে একটি কর্মক্ষমতা-পরীক্ষা কাঠামো ব্যবহার করুন৷ একটি সম্ভাব্য পছন্দ হল আর্টিলারি , যা আপনি একটি একক লাইন দিয়ে আহ্বান করতে পারেন:

$ artillery quick -d 300 -r 30 URL

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

পরীক্ষা করার পরে, ক্লাউড কনসোলে ক্লাউড ফাংশন API কোটা পৃষ্ঠায় আপনার সংযোগ কোটার ব্যবহার পরীক্ষা করুন। যদি ব্যবহার ধারাবাহিকভাবে প্রায় 30 (বা এর একাধিক) হয় তবে আপনি প্রতিটি আহ্বানে একটি (বা একাধিক) সংযোগ স্থাপন করছেন। আপনি আপনার কোড অপ্টিমাইজ করার পরে, আপনি দেখতে পাবেন কয়েকটি (10-30) সংযোগ শুধুমাত্র পরীক্ষার শুরুতে ঘটবে।

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