Cloud Functions সরলতা আপনাকে দ্রুত কোড তৈরি করতে এবং সার্ভারবিহীন পরিবেশে তা চালাতে সাহায্য করে। মাঝারি পরিসরে, ফাংশন চালানোর খরচ কম থাকে এবং আপনার কোড অপ্টিমাইজ করাকে খুব বেশি অগ্রাধিকারের বিষয় বলে মনে নাও হতে পারে। কিন্তু, আপনার ডেপ্লয়মেন্টের পরিধি বাড়ার সাথে সাথে, কোড অপ্টিমাইজ করা ক্রমশ গুরুত্বপূর্ণ হয়ে ওঠে।
এই ডকুমেন্টটিতে আপনার ফাংশনগুলোর জন্য নেটওয়ার্কিং অপ্টিমাইজ করার পদ্ধতি বর্ণনা করা হয়েছে। নেটওয়ার্কিং অপ্টিমাইজ করার কিছু সুবিধা নিচে দেওয়া হলো:
- প্রতিটি ফাংশন কলে নতুন আউটবাউন্ড সংযোগ স্থাপনে ব্যয়িত সিপিইউ সময় হ্রাস করুন।
- কানেকশন বা ডিএনএস কোটা ফুরিয়ে যাওয়ার সম্ভাবনা হ্রাস করুন।
স্থায়ী সংযোগ বজায় রাখা
এই অংশে একটি ফাংশনে কীভাবে স্থায়ী সংযোগ বজায় রাখা যায় তার উদাহরণ দেওয়া হয়েছে। এটি করতে ব্যর্থ হলে সংযোগ কোটা দ্রুত শেষ হয়ে যেতে পারে।
এই বিভাগে নিম্নলিখিত পরিস্থিতিগুলো আলোচনা করা হয়েছে:
- HTTP/S
- গুগল এপিআই
HTTP/S অনুরোধ
নিচের অপ্টিমাইজ করা কোড স্নিপেটটি দেখায়, কীভাবে প্রতিটি ফাংশন আহ্বানের সময় একটি নতুন সংযোগ তৈরি করার পরিবর্তে স্থায়ী সংযোগ বজায় রাখা যায়:
নোড.জেএস
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 অবজেক্টে পরিণত করা যায়।
গুগল এপিআই অ্যাক্সেস করা
নীচের উদাহরণটিতে ক্লাউড পাব/সাব (Cloud Pub/Sub) ব্যবহার করা হয়েছে, কিন্তু এই পদ্ধতিটি অন্যান্য ক্লায়েন্ট লাইব্রেরির ক্ষেত্রেও কাজ করে—যেমন, ক্লাউড ন্যাচারাল ল্যাঙ্গুয়েজ (Cloud Natural Language) বা ক্লাউড স্প্যানার (Cloud Spanner )। উল্লেখ্য যে, কর্মক্ষমতার উন্নতি নির্দিষ্ট ক্লায়েন্ট লাইব্রেরির বর্তমান বাস্তবায়নের উপর নির্ভর করতে পারে।
একটি Pub/Sub ক্লায়েন্ট অবজেক্ট তৈরি করলে প্রতিবার ব্যবহারের জন্য একটি সংযোগ এবং দুটি DNS কোয়েরি তৈরি হয়। অপ্রয়োজনীয় সংযোগ এবং DNS কোয়েরি এড়াতে, নীচের নমুনায় দেখানো অনুযায়ী Pub/Sub ক্লায়েন্ট অবজেক্টটি গ্লোবাল স্কোপে তৈরি করুন:
নোড.জেএস
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 অবজেক্টে পরিণত করা যায়।
পাইথন ৩.৭ রানটাইমে GCP_PROJECT এনভায়রনমেন্ট ভেরিয়েবলটি স্বয়ংক্রিয়ভাবে সেট হয়ে যায়। পরবর্তী রানটাইমগুলোতে, ফাংশন ডিপ্লয়মেন্টের সময় এটি নির্দিষ্ট করে দেওয়া নিশ্চিত করুন। এনভায়রনমেন্ট ভেরিয়েবল কনফিগার করার পদ্ধতি দেখুন।
বহির্গামী সংযোগ
বহির্গামী অনুরোধের সময়সীমা
আপনার ফাংশন থেকে VPC নেটওয়ার্কে করা অনুরোধগুলো ১০ মিনিট নিষ্ক্রিয় থাকার পর টাইমআউট হয়ে যায়। আপনার ফাংশন থেকে ইন্টারনেটে করা অনুরোধগুলো ২০ মিনিট নিষ্ক্রিয় থাকার পর টাইমআউট হয়ে যায়।
বহির্গামী সংযোগ রিসেট
অন্তর্নিহিত পরিকাঠামো পুনরায় চালু বা আপডেট করার সময় আপনার ফাংশন থেকে VPC নেটওয়ার্ক এবং ইন্টারনেট উভয়ের সংযোগ প্রবাহ মাঝে মাঝে বিচ্ছিন্ন ও প্রতিস্থাপিত হতে পারে। যদি আপনার অ্যাপ্লিকেশন দীর্ঘস্থায়ী সংযোগগুলি পুনরায় ব্যবহার করে, তবে আমরা সুপারিশ করি যে আপনি একটি অচল সংযোগের পুনঃব্যবহার এড়াতে আপনার অ্যাপ্লিকেশনটিকে সংযোগগুলি পুনরায় স্থাপন করার জন্য কনফিগার করুন।
আপনার ফাংশনের লোড-টেস্টিং
আপনার ফাংশনটি গড়ে কতগুলো কানেকশন সম্পন্ন করে তা পরিমাপ করতে, এটিকে একটি HTTP ফাংশন হিসেবে ডেপ্লয় করুন এবং একটি পারফরম্যান্স-টেস্টিং ফ্রেমওয়ার্ক ব্যবহার করে নির্দিষ্ট QPS-এ এটিকে কল করুন। এর একটি সম্ভাব্য বিকল্প হলো Artillery , যা আপনি মাত্র একটি লাইনে কল করতে পারেন:
$ artillery quick -d 300 -r 30 URL
এই কমান্ডটি ৩০০ সেকেন্ড ধরে প্রতি সেকেন্ডে ৩০টি কোয়েরি (QPS) হারে প্রদত্ত URL-টি ফেচ করে।
পরীক্ষাটি সম্পন্ন করার পর, ক্লাউড কনসোলের Cloud Functions এপিআই কোটা পৃষ্ঠায় আপনার সংযোগ কোটার ব্যবহার পরীক্ষা করুন। যদি ব্যবহার ধারাবাহিকভাবে ৩০ (বা এর গুণিতক)-এর কাছাকাছি থাকে, তাহলে আপনি প্রতিটি আহ্বানে একটি (বা একাধিক) সংযোগ স্থাপন করছেন। আপনার কোড অপ্টিমাইজ করার পর, আপনি দেখবেন যে পরীক্ষার শুরুতে কেবল কয়েকটি (১০-৩০) সংযোগ ঘটছে।
এছাড়াও আপনি একই পৃষ্ঠায় থাকা সিপিইউ কোটা প্লটে অপ্টিমাইজেশনের আগে ও পরের সিপিইউ খরচের তুলনা করতে পারেন।