Cloud Functions-এর সরলতা আপনাকে দ্রুত কোড ডেভেলপ করতে এবং এটি সার্ভারলেস এনভায়রনমেন্টে রান করতে দেয়। মাঝারি স্কেলে, ফাংশন চালানোর খরচ কম হয় এবং আপনার কোড অপ্টিমাইজ করাকে খুব বেশি অগ্রাধিকার দেওয়ার প্রয়োজন নাও হতে পারে। আপনার ডেপ্লয়মেন্টের স্কেল বাড়ার সাথে সাথে, আপনার কোড অপ্টিমাইজ করা ক্রমশ গুরুত্বপূর্ণ হয়ে ওঠে।
আপনার ফাংশনের জন্য নেটওয়ার্কিং কীভাবে অপ্টিমাইজ করবেন তা এই ডকুমেন্টে বর্ণনা করা হয়েছে। নেটওয়ার্কিং অপ্টিমাইজ করার কিছু সুবিধা নিচে উল্লেখ করা হল:
- প্রতিটি ফাংশন কলে নতুন আউটবাউন্ড কানেকশন তৈরি করার জন্য খরচ করা 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(); });
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 quick -d 300 -r 30 URL
এই কমান্ডটি প্রদত্ত URL-কে ৩০০ সেকেন্ডের জন্য ৩০ QPS-এ ফেচ করে।
টেস্ট করার পরে, Google Cloud কনসোলে Cloud Functions API কোটা পৃষ্ঠায় আপনার কানেকশন কোটার ব্যবহার চেক করুন। ব্যবহার যদি ধারাবাহিকভাবে ৩০ (বা এর মাল্টিপল) হয়, তাহলে আপনি প্রতিটি ইনভোকেশনে একটি (বা একাধিক) কানেকশন স্থাপন করছেন। আপনার কোড অপ্টিমাইজ করার পরে, আপনি দেখতে পাবেন যে পরীক্ষার শুরুতে কয়েকটি (১০-৩০) কানেকশন তৈরি হয়েছে।
এছাড়াও, একই পৃষ্ঠায় CPU কোটা প্লটে অপ্টিমাইজেশনের আগে ও পরে CPU খরচের তুলনা করতে পারবেন।