Course-এর সূচি

1.2

Server আসলে কী? Hardware, Software এবং একটি Machine কীভাবে হাজারো মানুষকে সেবা দেয়

Machine এবং Program: Port-এ Listen করা, একসঙ্গে অনেক Client সামলানো, Server-এর ধরন, এবং Server কোথায় থাকে।

32 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই Lesson শেষে তুমি পারবে

  • Server আসলে কী তা ব্যাখ্যা করতে: একটি Program-এর ভূমিকা, এবং যে কম্পিউটারে Program-টি চলে।
  • একটি Server Program চালু হওয়ার মুহূর্ত থেকে কী করে তা বর্ণনা করতে: socket, bind, listen, accept, এবং কেন সেটি “address in use”, “connection refused” বা Timeout দিয়ে ব্যর্থ হয়।
  • একটি Request-কে Server-এর ভেতর দিয়ে অনুসরণ করতে, এবং প্রতিটি ধাপে কোন Resource খরচ হয় তা বলতে (CPU, RAM, Disk, Network, File Descriptor)।
  • একটি Server কীভাবে একসঙ্গে হাজারো Client সামলায় তার পদ্ধতিগুলো তুলনা করতে: Process, Thread, Event Loop ও Hybrid, এবং তাদের ব্যর্থতার ধরন।
  • Server Hardware ও Server অপারেটিং সিস্টেম PC থেকে কীভাবে আলাদা, এবং কেন Redundancy, ECC Memory ও Remote Management জরুরি তা বলতে।
  • প্রচলিত ধরনের Server ও তাদের Port চিনতে, এবং কোথায় চালাবে তা বেছে নিতে: Bare Metal, VM, Container না Serverless।
  • Scaling, Health Check ও Availability-র “Nines” ব্যাখ্যা করতে, এবং Production-এ Server সাধারণত যেভাবে ব্যর্থ হয় তা চিনতে।

#Server আসলে কী

আগের Lesson-এ দেখেছ Client প্রশ্ন করে আর Server উত্তর দেয়। তাহলে যে জিনিসটি উত্তর দেয়, সেটি আসলে কী?

Server শব্দটি দুটি জিনিস বোঝাতে ব্যবহৃত হয়, আর দুটোই সঠিক:

  1. Program, যে Request-এর অপেক্ষায় থাকে এবং উত্তর দেয়। Nginx, একটি Node.js App, PostgreSQL, একটি DNS Resolver, একটি Minecraft Server সবই Server Program।
  2. কম্পিউটার, যেখানে Program-টি চলে। কেউ যখন বলে “আমরা তিনটি Server কিনেছি” বা “Server টা সিঙ্গাপুরে”, তখন সে মেশিনটির কথা বলছে।

মূল কথা হলো “Server” একটি ভূমিকা (Role), বিশেষ কোনো বাক্স নয়। যেকোনো কম্পিউটার সেই মুহূর্তেই Server হয়ে যায় যখন সে এমন একটি Program চালায় যা অন্যদের Request-এর জন্য Listen করে। npm run dev চালালে তোমার Laptop একটি Server; একটি পুরনো Android ফোনও Web Server হতে পারে; আলমারিতে রাখা একটি Raspberry Pi পুরো পরিবারের ছবি পরিবেশন করতে পারে। Data Centre-এর Server হলো এমন কম্পিউটার, যা দিনরাত, প্রতিদিন, না থেমে এই কাজটি করার জন্যই তৈরি।

এই ভূমিকা আপেক্ষিকও। একটি Web Application Browser-এর কাছে Server, কিন্তু নিজের Database, Cache বা Payment API-এর কাছে সে একজন Client। বড় System-এ প্রায় প্রতিটি অংশই কারও না কারও Server, আবার অন্য কারও Client।

#Server Program: একটি Process যে Listen করে

Server Program হলো একটি দীর্ঘক্ষণ চলা Process। সাধারণ Program (ক্যালকুলেটর, একটি Script) চালু হয়, কাজ করে, বন্ধ হয়ে যায়। Server চালু হয়ে অপেক্ষা করে, কখনো কয়েক মাস ধরে, যা আসে তার উত্তর দেয়।

#অপারেটিং সিস্টেম চালু করে ও বাঁচিয়ে রাখে

Linux-এ এমন Background Program-কে বলে Daemon (অনেকের নাম d দিয়ে শেষ: sshd, systemd, httpd); Windows-এ বলে Service। এগুলো খুব কমই হাতে চালু করা হয়। কাজটি করে একটি Service Manager: প্রায় সব আধুনিক Linux-এ systemd, Windows-এ Service Control Manager, অথবা Docker বা Kubernetes-এর মতো Container Platform। Service Manager:

  • Boot-এর সময় Program চালু করে, নির্দিষ্ট একটি User Account-এ (নিরাপত্তার জন্য Root নয়);
  • Crash করলে আবার চালু করে (Restart=on-failure);
  • তার Output Log-এ জমা করে (journalctl -u myapp);
  • Shutdown-এর সময় ভদ্রভাবে থামায়।

একটি Node.js Server-এর জন্য ছোট্ট একটি systemd Unit দেখতে এমন:

# /etc/systemd/system/myapp.service
[Unit]
Description=My API server
After=network.target

[Service]
User=myapp
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node server.js
Restart=on-failure
Environment=PORT=8080

[Install]
WantedBy=multi-user.target

#Socket, bind, listen, accept

Network Card ছুঁতে পারে শুধু অপারেটিং সিস্টেমের Kernel, তাই Server ছোট ও নির্দিষ্ট কয়েকটি System Call দিয়ে Kernel-এর সাহায্য নেয়। যেকোনো ভাষায় লেখা প্রতিটি Server এই চারটি ধাপ করে:

  1. socket(): “আমাকে একটি Network Endpoint দাও”। Kernel একটি ছোট সংখ্যা ফেরত দেয়, যাকে বলে File Descriptor।
  2. bind(address, port): “আমি এই IP Address ও Port-এ Connection নিতে চাই”, যেমন 0.0.0.0:8080।
  3. listen(backlog): “আমার হয়ে Connection নেওয়া শুরু করো”। এখন থেকে Kernel নিজেই TCP Handshake শেষ করে এবং সম্পূর্ণ Connection-গুলো Backlog-এর দৈর্ঘ্য পর্যন্ত Queue-তে রাখে।
  4. accept(): “অপেক্ষারত পরের Connection-টি দাও”। এটি শুধু ওই Client-এর জন্য একটি নতুন Socket ফেরত দেয়; Listening Socket অন্যদের জন্য খোলা থাকে। কেউ অপেক্ষায় না থাকলে Process এখানে ঘুমিয়ে থাকে, কোনো CPU খরচ না করে।

এরপর প্রতিটি Connection-এর জন্য Program Request পড়ে, প্রক্রিয়া করে, Response লেখে, Log করে, তারপর Connection বন্ধ করে অথবা পরের Request-এর জন্য খোলা রাখে (Keep-alive)। দেখো কীভাবে ঘটে, আর সাধারণত যে চারভাবে ভুল হয়:

একটি Server Program যেভাবে চালু হয়

Program অপারেটিং সিস্টেমের কাছে একটি Socket চায়, একটি Port দখল করে, তারপর অপেক্ষা করে। একটি পরিস্থিতি বেছে নাও: স্বাভাবিক পথ আর চারটি পরিচিত ব্যর্থতা দেখো।

পরিস্থিতি

socket → bind → listen → accept, তারপর একটি Request ও একটি Response।

Server ProcessPID 4121
OS Kernel203.0.113.10
Client (অন্য Machine)198.51.100.7
systemd চালু করেছে
ধাপ 1 / 11
1

Boot-এর সময় Service Manager (Linux-এ systemd) Program-টিকে Background Process হিসেবে চালু করে। সে একটি Process ID (PID) পায় এবং কেউ বন্ধ না করা পর্যন্ত চলতে থাকে।

#কোন Address-এ Listen করছ, তা গুরুত্বপূর্ণ

একটি মেশিনের সাধারণত কয়েকটি Address থাকে: Loopback Address 127.0.0.1, 192.168.1.20-এর মতো একটি LAN Address, হয়তো একটি Public Address। তুমি কোন Address-এ bind করছ, তা ঠিক করে কে তোমার কাছে পৌঁছাতে পারবে:

Bind Addressকে Connect করতে পারেসাধারণ ব্যবহার
127.0.0.1 (বা ::1, বা localhost)শুধু একই মেশিনের ProgramDevelopment Server, যে Database শুধু Local App ব্যবহার করে, Admin Panel
0.0.0.0মেশিনের যেকোনো IPv4 Address-এ পৌঁছাতে পারে এমন যে কেউPublic Server
::যেকোনো IPv6 Address, আর বেশিরভাগ System-এ IPv4-ওPublic Server (Dual-stack)
নির্দিষ্ট একটি Address, যেমন 192.168.1.20শুধু ওই Address-এ পাঠানো Trafficএকাধিক Network-ওয়ালা মেশিন, যেমন একটি Public ও একটি Private

#এক অনুচ্ছেদে Port

Port-এর সঙ্গে তোমার পরিচয় হয়েছে Addressing-এ: IP Address Packet-কে মেশিনে পৌঁছায়, Port পৌঁছায় সঠিক Program-এ, আর প্রতিটি Connection আলাদা করা হয় তার 5-tuple দিয়ে। Server-এর জন্য দুটি ব্যবহারিক নিয়ম: একটি IP ও Port-এ একটিমাত্র Process Listen করতে পারে (দ্বিতীয়টি পায় EADDRINUSE, “address already in use”), আর Linux-এ ১০২৪-এর নিচের Port বিশেষ অধিকারপ্রাপ্ত (Privileged), তাই সাধারণ User 80 বা 443-এ Bind করতে পারে না। Server এর সমাধান করে Root হিসেবে চালু হয়ে পরে অধিকার ছেড়ে দিয়ে, CAP_NET_BIND_SERVICE Capability পেয়ে, অথবা সবচেয়ে বেশি দেখা যায়: 8080-এর মতো উঁচু Port-এ Listen করে, আর 443 ধরে রাখে সামনের একটি Reverse Proxy বা Load Balancer।

#Connect ব্যর্থ হলে: লক্ষণটি পড়ো

কী দেখছএর মানেপ্রথমে কী দেখবে
Server চালু করার সময় address already in useঅন্য একটি Process আগে থেকেই Port-টি ধরে আছে, প্রায়ই একই Server-এর পুরনো কপিss -tlnp / netstat -ano দিয়ে খুঁজে বের করো; বন্ধ করো বা Port বদলাও
সঙ্গে সঙ্গে Connection Refusedমেশিনে পৌঁছানো যায়, কিন্তু ওই Port ও Address-এ কেউ Listen করছে না (Kernel একটি TCP RST পাঠায়)Process চলছে কি? 127.0.0.1-এ Bind করা কি? Port ঠিক আছে কি?
অনেক সেকেন্ড পর TimeoutPacket চুপচাপ ফেলে দেওয়া হচ্ছে: Firewall বা Cloud Security Group, অথবা Host বন্ধ বা পৌঁছানো যায় নাFirewall Rule, Security Group, Routing, মেশিন চালু কি না
Connect হয়, তারপর কোনো Response ছাড়াই আটকে থাকেServer Connection Accept করেছে কিন্তু আটকে আছে: অতিরিক্ত চাপ, Block, বা কোনো Dependency-র অপেক্ষাServer-এর CPU, Log, ধীর Database, Thread Pool (নিচে দেখো)

#একটি Request-এর ভেতরে

Connection Accept হওয়ার পর একটি সাধারণ Web বা API Server প্রতিটি Request-এর জন্য একই Pipeline চালায়:

  1. ১. পড়া ও Parse করা

    Socket থেকে Byte পড়ে Method, Path, Header ও Body-তে Parse করা। TLS এখানে শেষ হলে আগে Decrypt করতে হয়। খরচ হয় CPU আর Buffer-এর জন্য সামান্য Memory।

  2. ২. যাচাই ও Route

    Middleware মৌলিক বিষয় দেখে: Caller কি Authenticated, Rate Limit পার হয়েছে কি, Input বৈধ কি? তারপর একটি Router Path (GET /products/42) মিলিয়ে একটি Handler Function বেছে নেয়। ভুল Request এখানেই ফিরিয়ে দাও, দামি কোনো কাজের আগে।

  3. ৩. Business Logic ও Dependency

    Handler আসল কাজটি করে, সাধারণত অন্য Server-কে Call করে: একটি Cache, একটি Database, অন্য একটি Internal Service, বা কোনো Third-party API। তাদের অপেক্ষায় থাকার সময় Request কোনো CPU খরচ করে না, কিন্তু তখনো ধরে রাখে Memory, Pool থেকে একটি Connection আর একটি File Descriptor। Request-এর মোট সময়ের বেশিরভাগই সাধারণত এই অপেক্ষা।

  4. ৪. Response তৈরি ও পাঠানো

    ফলাফলকে HTML বা JSON-এ রূপান্তর (CPU), Header ও Status Code যোগ, তারপর Socket-এ লেখা (Network)।

  5. ৫. Log ও পরিষ্কার করা

    একটি Access-log লাইন লেখা (Disk বা Log Pipeline), Metric রেকর্ড করা, Pool-এর Connection ফেরত দেওয়া, তারপর Socket বন্ধ করা বা Keep-alive রাখা।

একটি Request-এর ভেতরে

Request পড়া আর Response লেখার মাঝে Server কী করে, এবং প্রতিটি ধাপে কী খরচ হয়।

পরিস্থিতি

একটি সাধারণ API Request যে সব ধাপ পার হয়।

ClientBrowser / App
App Serverapi.example.com
CacheRedis
DatabasePostgreSQL
GET /products/42
ধাপ 1 / 10
1

Request একটি Accept করা Connection-এ আসে। Connection-টি ধরে রাখতে খরচ হয় একটি File Descriptor ও কয়েক Kilobyte Kernel Buffer Memory।

এই প্রতিটি Resource সীমিত, আর প্রতিটির ফুরিয়ে যাওয়ার নিজস্ব ধরন আছে:

Resourceকীসে লাগেফুরিয়ে গেলে
CPUParse, TLS, Template, JSON, তোমার CodeRequest Queue-তে জমে, Latency বাড়ে; Load Average Core-সংখ্যার ওপরে
RAMBuffer, প্রতি Connection-এর State, Cache, Thread StackSwapping-এ সব ধীর হয়, তারপর OOM Killer Process বন্ধ করে দেয়
Disk I/O ও জায়গাLog, Upload করা File, Local Databaseধীর Write Request আটকে দেয়; Disk ভরে গেলে Write ব্যর্থ হয়
Networkআসা-যাওয়া ByteBandwidth-এর সীমায় পৌঁছায়, Packet ফেলে দেওয়া হয়, Timeout
File Descriptorপ্রতিটি খোলা Socket ও FileToo many open files (EMFILE): নতুন Connection প্রত্যাখ্যাত হয়
Pool ConnectionDatabase বা Upstream ConnectionRequest খালি Connection-এর অপেক্ষা করে, তারপর Timeout

#একসঙ্গে হাজারো জনকে সেবা

জনপ্রিয় একটি Server-এ একই মুহূর্তে হাজার হাজার Connection খোলা থাকে। CPU একসঙ্গে ততগুলো কাজই চালাতে পারে যতগুলো তার Core, তাহলে একটি মেশিন হাজারো কথোপকথন চালায় কীভাবে? এর কয়েকটি ক্লাসিক নকশা আছে, যাদের বলে Concurrency Model।

#একবারে একজন (Iterative)

সবচেয়ে সরল Server একটি Loop চালায়: একটি Connection Accept করো, তাকে পুরোপুরি সেবা দাও, তারপর পরেরটি Accept করো। সে যখন Database-এর অপেক্ষায়, বাকি সবাইও অপেক্ষায়। খেলনা হিসেবে চলে, আসল Traffic-এ একদম অচল।

#প্রতি Connection-এ একটি Process

একটি Connection Accept করো, তারপর fork() দিয়ে পুরো Process-এর একটি কপি বানিয়ে তাকে দাও। প্রতিটি Client নিজের Process পায়, সম্পূর্ণ আলাদা: একটি Crash করলে বাকিদের কিছু হয় না। ক্লাসিক Unix Daemon আর Apache-এর পুরনো “prefork” Mode এভাবে কাজ করত, আর PostgreSQL এখনো প্রতিটি Database Connection-এর জন্য একটি Process চালায়। খরচ: প্রতিটি Process কয়েক Megabyte Memory নেয়, আর শত শত Process-এর মধ্যে Switch করতে CPU নষ্ট হয়, তাই এটি শত থেকে কয়েক হাজার Connection-এই আটকে যায়।

#প্রতি Connection-এ একটি Thread (এবং Thread Pool)

Thread Process-এর চেয়ে হালকা, কারণ তারা একই Memory ভাগ করে। প্রতিটি Connection একটি Thread পায়, সাধারণত আগে থেকে তৈরি একটি Pool থেকে (যেমন ২০০টি Thread)। Code থাকে সহজ, ওপর থেকে নিচে লেখা (“পড়ো, Query করো, লেখো”), আর একটি Thread Database-এ আটকে থাকলে অপারেটিং সিস্টেম অন্য Thread চালায়। Tomcat-এর মতো ক্লাসিক Java Server এভাবে কাজ করে।

সীমাবদ্ধতা: প্রতিটি Thread নিজের Stack আলাদা করে রাখে (প্রায় ১ MB থেকে ৮ MB Address Space), Switch করতে CPU খরচ হয়, আর Pool একটি শক্ত ছাদ। সব Thread ব্যস্ত থাকলে নতুন Request Queue-তে অপেক্ষা করে, এমনকি যদি সব Thread শুধু ধীর কোনো কিছুর অপেক্ষায় বসে থাকে। একেই বলে Thread-pool Exhaustion, আর ধীর Database যেমন সহজে এটি ঘটায়, ধীর Client-ও তেমনি।

#Non-blocking I/O-সহ Event Loop

প্রতি Connection-এ একটি Thread-এর বদলে অনেক Connection-এর জন্য একটি Thread। Socket-গুলো Non-blocking Mode-এ রাখা হয় এবং একটি দক্ষ Readiness API দিয়ে Kernel-এ নিবন্ধন করা হয়: Linux-এ epoll, macOS ও BSD-তে kqueue, Windows-এ IOCP। Thread একটি Loop চালায়:

  1. Kernel-কে জিজ্ঞেস করো: “আমার ১০,০০০ Socket-এর মধ্যে কোনগুলো তৈরি?”
  2. প্রতিটি তৈরি Socket-এ একটু কাজ করো: যা এসেছে পড়ো, একটি Database Query শুরু করো, পাঠানোর মতো যা তৈরি তা লেখো। কখনো অপেক্ষা কোরো না।
  3. ১ নম্বর ধাপে ফিরে যাও।

অপেক্ষারত একটি Connection-এর খরচ মাত্র কয়েক Kilobyte State, পুরো একটি Thread নয়, তাই একটি Loop হাজার হাজার প্রায়-অলস Connection ধরে রাখতে পারে। Nginx, Node.js, Redis, HAProxy আর Python-এর asyncio এভাবেই তৈরি।

শর্ত একটাই: Loop কখনো Block হতে পারবে না। একটিমাত্র CPU-ভারী কাজ (ছবি Resize, উচ্চ Cost-এ Password Hash, বিশাল JSON File Parse) বা একটি Synchronous Call Loop থামিয়ে দেয়, আর ওই সময়টুকু তার ওপরের প্রতিটি Connection জমে থাকে। ভারী কাজ যায় Worker Thread, Background Job Queue বা অন্য Service-এ। উদাহরণ হিসেবে, Node.js File System-এর কাজ, DNS Lookup আর কিছু Crypto-র জন্য চুপচাপ একটি ছোট Thread Pool (Default ৪টি Thread) ব্যবহার করে।

#Hybrid: প্রতি Core-এ একটি Event Loop

একটি Event Loop চলে একটি Core-এ। ১৬ Core-এর মেশিন কাজে লাগাতে চালাও ১৬টি Worker Process, প্রত্যেকের নিজস্ব Event Loop, সবাই একই Listening Port ভাগ করে নেয়। Nginx ঠিক এটাই করে (worker_processes auto;), Node.js করে তার Cluster Module দিয়ে, আর Python Server চালায় কয়েকটি Async Worker। অনেক আধুনিক Runtime (Go, Java-র Virtual Thread, Rust-এর Tokio) আরও এগিয়ে: তুমি সহজ Blocking-ধাঁচের Code লেখো, আর Runtime হাজারো হালকা Task-কে কয়েকটি Thread-এ ভাগ করে চালায়।

একটি Server কীভাবে অনেক Client সামলায়

চারজন Client একসঙ্গে আসে। প্রতিটি Request-এর লাগে প্রায় ১০ ms CPU আর ৫০ ms-এর একটি Database Call। দেখো প্রতিটি মডেল তার Worker-দের কীভাবে খাটায়।

পরিস্থিতি

Iterative Server: একজন Worker, বাকি সবাই অপেক্ষায়।

Client A
Client B
Client C
Client D
Accept QueueKernel Backlog
Worker 1
Worker 2ব্যবহৃত নয়
Worker 3ব্যবহৃত নয়
Database~50 ms
ধাপ 1 / 4
1

চারজন Client একসঙ্গে Connect করে। Kernel তাদের Handshake শেষ করে Accept Queue-তে রেখে দেয়।

Modelশক্তিদুর্বলতাকোথায় দেখা যায়
Iterativeলেখা খুব সহজএকবারে একজন Clientশেখানোর উদাহরণ, nc -l
প্রতি Connection-এ Processশক্ত বিচ্ছিন্নতা; Crash-এ ক্ষতি একজন Client-এরভারী Memory; শত থেকে কয়েক হাজার Connectionক্লাসিক Unix Daemon, Apache prefork, PostgreSQL
প্রতি Connection-এ Thread / Poolসহজ Blocking Code; সব Core কাজে লাগেStack Memory ও Switching; Pool ExhaustionTomcat, ক্লাসিক Java ও .NET Server
Event Loopপ্রচুর অলস Connection, কম Memoryযেকোনো Blocking বা CPU-ভারী Code সবাইকে থামিয়ে দেয়; প্রতি Loop-এ একটি CoreNode.js, Redis
প্রতি Core-এ Event LoopNetwork-ভারী কাজে দুইয়ের সেরাটাবেশি জটিল; Worker-দের মধ্যে State ভাগ হয় নাNginx, HAProxy, Cluster করা Node.js

#C10K সমস্যা

১৯৯৯ সালের দিকে Engineer Dan Kegel প্রশ্ন তোলেন, একটি Server কীভাবে ১০,০০০ Concurrent Connection সামলাবে, যা তখনকার Thread- ও Process-per-connection Server পারত না। উত্তর ছিল ওপরের Event-driven নকশা, আর এমন Kernel API (epoll, kqueue) যা হাজারো Socket-এর সবগুলো না ঘেঁটেই বলে দেয় কোনগুলো তৈরি। এই সমস্যা থেকেই Nginx-এর জন্ম; সেই গল্প আছে Web Server ও App Server Lesson-এ। আজ ভালোভাবে Tune করা একটি মেশিন লাখ লাখ প্রায়-অলস Connection ধরে রাখে।

#Queue, Backlog, এবং “Overloaded” দেখতে কেমন

যে কাজ এখনই সেবা পাচ্ছে না, সে একটি Queue-তে অপেক্ষা করে, আর প্রতিটি স্তরে Queue আছে: Kernel-এর Accept Backlog (listen()-এর Argument; Linux-এ net.core.somaxconn দিয়ে সীমিত, সাম্প্রতিক Kernel-এ Default 4096), Thread Pool-এর Queue, Database Pool-এর Queue। Queue ছোট ছোট চাপ সামলে নেয়। কিন্তু Traffic যদি Capacity-র ওপরে থাকতেই থাকে, Queue শুধু ভরতে থাকে, আর তুমি ক্রমানুসারে দেখো:

  1. Latency বাড়ে, অথচ Throughput একই থাকে: Request সেবা পাওয়ার চেয়ে অপেক্ষায় বেশি সময় কাটায়।
  2. Timeout শুরু হয়: Client হাল ছেড়ে দেয়, প্রায়ই Retry করে, আর আরও চাপ বাড়ায় (Retry Storm)।
  3. Error: Accept Queue উপচে পড়ে আর নতুন Connection ফেলে দেওয়া হয়, Proxy 502/503/504 দেয়, Process-এর Memory বা Descriptor ফুরিয়ে যায়।

সুস্থ Server অতিরিক্ত চাপে আগেভাগেই ফিরিয়ে দেয় (Retry-After-সহ দ্রুত একটি 503, বা Rate Limiting), সবকিছু নিয়ে নিয়ে সবার জন্য Timeout ঘটানোর বদলে।

#Throughput, Latency ও Little’s Law

  • Latency হলো একটি Request-এ কত সময় লাগে (শুধু গড় নয়, ৯৯তম Percentile দেখো, অর্থাৎ সবচেয়ে ধীর ১%)।
  • Throughput হলো প্রতি সেকেন্ডে কতগুলো Request সম্পন্ন হয়।

এদের জোড়া লাগায় Little’s Law: চলমান Request-এর সংখ্যা = আসার হার × প্রতিটিতে লাগা সময় (L = λ × W)। প্রতি সেকেন্ডে ১,০০০ Request আর প্রতিটিতে ০.২ সেকেন্ড হলে যেকোনো মুহূর্তে প্রায় ২০০টি Request চলমান, তাই Thread-per-request Server-এর অন্তত ২০০টি Thread লাগবে। Database ধীর হয়ে প্রতিটি Request-এ ২ সেকেন্ড লাগলে একই Traffic-এ লাগবে ২,০০০: এভাবেই একটি ধীর Dependency এমন Pool-ও শেষ করে দেয় যেটি দেখতে যথেষ্ট বড় মনে হচ্ছিল।

নিজেকে যাচাই করোপ্রশ্ন

একটি Node.js Server স্বচ্ছন্দে ৫,০০০ Connection সামলায়। একটি Release-এর পর হঠাৎ প্রতিটি Request-এ প্রায় ৯০০ ms বেশি লাগছে, এমনকি সাধারণ Health Check-এও। একটি Core-এ CPU ১০০%। সবচেয়ে সম্ভাব্য কারণ কী?

#Server Hardware: শুধু বড় একটি PC নয়

শারীরিকভাবে Server-এ PC-র মতোই যন্ত্রাংশ: CPU, RAM, Storage, Network Card, Power Supply। পার্থক্য হলো এটি এমনভাবে নকশা করা যাতে বছরের পর বছর ২৪ ঘণ্টা চলে, বন্ধ না করেই মেরামত করা যায়, এবং দূর থেকে পরিচালনা করা যায়।

Desktop PCসাধারণ Data-centre Server
আকারটেবিলের নিচে TowerRack-এ বসানো চ্যাপ্টা বাক্স: 1U (১.৭৫ ইঞ্চি / ৪৪.৪৫ mm উঁচু) বা 2U, একটি Standard Rack-এ ৪২ Unit
CPU১টি Chip, ৬–১৬ Core১–২টি Socket, প্রায়ই প্রতিটিতে ৩২–১২৮+ Core (Intel Xeon ও একই ধরনের Server Chip), GHz কম কিন্তু Core অনেক বেশি
Memory১৬–৬৪ GB, সাধারণ২৫৬ GB থেকে কয়েক TB, ECC
Storage১টি SSDঅনেকগুলো Hot-swap SSD/NVMe বা HDD Bay, সাধারণত RAID-এ
Power১টি Power Supply২টি Redundant Hot-swap PSU, আলাদা Power Feed-এ
Network১টি Port, 1 Gbps২+ Port, 10–100 Gbps, ভিন্ন ভিন্ন Switch-এ যুক্ত
DisplayMonitor, Keyboard, MouseHeadless: কোনো Monitor নেই, Network দিয়ে পরিচালিত
Remote Controlনেইনিজস্ব Network Port-সহ BMC (IPMI; Dell একে বলে iDRAC, Hewlett Packard Enterprise বলে iLO)
শীতলীকরণ ও শব্দনিঃশব্দজোরালো Fan, ঠান্ডা ঘরে সামনে থেকে পেছনে বাতাস

এর কয়েকটি বোঝা দরকার:

  • ECC Memory। RAM মাঝে মাঝে নিজে থেকেই একটি Bit উল্টে ফেলে (বৈদ্যুতিক Noise, এমনকি মহাজাগতিক রশ্মি)। PC-তে এতে হয়তো বছরে একবার একটি Game Crash করে। কিন্তু এক Terabyte Memory-ওয়ালা, বছরের পর বছর চলা Server-এ এটি চুপচাপ কোনো ব্যাংক Balance বা Database Page নষ্ট করে দিতে পারে। Error-Correcting Code Memory বাড়তি Bit রাখে, ফলে একটি Bit-এর ভুল নিজেই ঠিক করে আর দুটি Bit-এর ভুল ধরতে পারে।
  • Redundancy ও Hot-swap। যে যন্ত্রাংশ ক্ষয়ে যায় (Disk, Fan, Power Supply) সেগুলো জোড়ায় থাকে, আর Server চলতে চলতেই সামনে বা পেছন দিয়ে বের করা যায়।
  • RAID। কয়েকটি Disk একসঙ্গে একটির মতো কাজ করে, যাতে একটি Disk নষ্ট হলে কিছুই হারায় না: RAID 1 দুটি Disk Mirror করে, RAID 5/6 কয়েকটি Disk-এ Parity ছড়িয়ে একটি/দুটি নষ্ট হওয়া সামলায়, RAID 10 গতির জন্য Mirror ও Stripe দুটোই করে। কয়টা Disk নষ্ট হলেও Array টিকে থাকবে, সেটা ভাগ্যের ব্যাপার না, Level-এর ব্যাপার: RAID 5-এ প্রথম নষ্ট Disk বদলে Rebuild শেষ হওয়ার আগেই দ্বিতীয়টা গেলে Data হারায়। আর বড় Disk-এর Rebuild-এ একদিনও লেগে যেতে পারে; ওই সময়টায় Array ধীর থাকে, ঝুঁকিতেও থাকে। RAID নষ্ট Disk থেকে রক্ষা করে, File মুছে ফেলা, Ransomware বা আগুন থেকে নয়। এটি Backup নয়।
  • Remote Management। BMC (Baseboard Management Controller) হলো Motherboard-এ বসানো একটি ছোট আলাদা কম্পিউটার, নিজস্ব Network Port ও বিদ্যুৎসহ। IPMI বা নির্মাতার Web Console দিয়ে এর মাধ্যমে একজন Admin হাজার কিলোমিটার দূর থেকে Screen দেখতে পারেন, জমে যাওয়া মেশিন Power-cycle করতে পারেন, Firmware Setting বদলাতে পারেন, এমনকি OS নতুন করে Install করতে পারেন।

নষ্ট যন্ত্রাংশেও টিকে থাকার মতো করে তৈরি

যে যন্ত্রাংশ প্রায়ই নষ্ট হয়, Server-এ তার প্রতিটি দুটি করে থাকে, আর System-এ থাকে দুটি Server। একটি যন্ত্রাংশ নষ্ট করে দেখো কী চলতে থাকে।

পরিস্থিতি

Load Balancer
Switch A
Switch B
Server 1২টি NIC
Server 2
PSU 1Power Feed A
PSU 2Power Feed B
Disk 1RAID 1
Disk 2RAID 1
BMCনিজস্ব Network Port
Admin (অনেক দূরে)
ধাপ 1 / 3
1

Load Balancer Switch A হয়ে দুটি Server-এই ব্যবহারকারীর Request পাঠায়।

#Data Centre

Server থাকে Data Centre-এ: এমন ভবন, যা Server-এর তিনটি প্রয়োজন ঘিরে নকশা করা।

  • বিদ্যুৎ: Grid থেকে দুটি স্বাধীন Feed, কয়েক মিনিট সামলানোর জন্য UPS Battery ব্যবস্থা, আর কয়েক ঘণ্টা বা কয়েক দিন চালানোর জন্য ডিজেল Generator।
  • শীতলীকরণ: Server তার প্রায় সব বিদ্যুৎকেই তাপে পরিণত করে। Rack সাজানো হয় গরম ও ঠান্ডা সারিতে (Hot ও Cold Aisle), সঙ্গে শিল্প-মানের Air Conditioning বা Liquid Cooling। পুরনো ভবনে শীতলীকরণে প্রায় Server-এর সমান বিদ্যুৎ খরচ হতে পারে।
  • Network: ভিন্ন ভিন্ন Provider থেকে, ভিন্ন পথে ভবনে ঢোকা কয়েকটি Fibre সংযোগ, সঙ্গে শারীরিক নিরাপত্তা (প্রহরী, Camera, Biometric দরজা)।

#Server অপারেটিং সিস্টেম

Internet-এর বেশিরভাগ Server চলে Linux-এ: Ubuntu Server, Debian, Red Hat Enterprise Linux (RHEL) ও তার বিনামূল্যের পুনর্নির্মাণ যেমন Rocky Linux, আর AWS-এ Amazon Linux। এছাড়া দেখবে Windows Server (Active Directory, Microsoft Application ও .NET Framework App-এর জন্য) আর FreeBSD (Netflix-এর Video Cache ও কিছু Network যন্ত্র)।

Server OS-কে আলাদা করে মূলত সে কী বাদ দেয় আর কীসে দক্ষ:

  • কোনো Graphical Interface নেই। GUI না থাকা মানে কম Memory খরচ, আর নষ্ট বা আক্রান্ত হওয়ার মতো জিনিস কম। মেশিন পরিচালনা করা হয় SSH-এর ওপর একটি CLI দিয়ে (Windows Server প্রায়ই PowerShell দিয়ে, বা সাবধানে RDP দিয়ে পরিচালিত হয়)।
  • দীর্ঘ Support। Server Release ৫–১০ বছর Security Update পায়, তাই ঘন ঘন Upgrade করতে বাধ্য হতে হয় না।
  • Service, Log ও Restart প্রথম শ্রেণির সুবিধা: systemctl status myapp, journalctl -u myapp -f, Restart Policy, Log Rotation।
  • অনেক Connection ও দীর্ঘ Uptime-এর জন্য Tune করা, এমন সীমাসহ (Open File, Memory) যা বাড়ানো যায়।
ssh deploy@203.0.113.10            # Server-এ Login
systemctl status myapp             # চলছে কি? কখন থেকে? শেষ কয়েকটি Log লাইন
sudo systemctl restart myapp       # আবার চালু করো
journalctl -u myapp --since "10 min ago"   # সাম্প্রতিক Log
df -h                              # Disk-এর জায়গা (Disk ভরে যাওয়া অনেক Outage-এর কারণ)
free -h                            # Memory

#Server-এর ধরন

“Server” একটি ভূমিকা বোঝায়, তাই Server-এর নাম হয় সে কী পরিবেশন করে তা দিয়ে। একটি বাস্তব Product একসঙ্গে অনেক ধরনের Server ব্যবহার করে:

একটি ছবি-শেয়ারিং App-এর পেছনের Server-গুলো

একটি Product, অনেক ধরনের Server, প্রত্যেকের একটি কাজ। একটি কাজ বেছে নাও আর দেখো কোন কোন Server অংশ নেয়।

পরিস্থিতি

Browser
DNS ServerUDP 53
CDN EdgeHTTPS 443
Load BalancerHTTPS 443
App Server×3 · :8080
CacheRedis 6379
DatabasePostgreSQL 5432
Object StorageS3
Message BrokerRabbitMQ
Worker
Mail ServerSMTP 587
photos.example.com?203.0.113.10
ধাপ 1 / 4
1

প্রথমে Browser-এর একটি IP Address দরকার। একটি DNS Server উত্তর দেয় “photos.example.com হলো 203.0.113.10”। DNS Server-ও Server: এরা UDP Port 53-এ Listen করে।

ধরনকী পরিবেশন করেসাধারণ Portউদাহরণ
Web ServerFile ও HTTP(S) Response; প্রায়ই Reverse Proxy-ও80, 443Nginx, Apache, Caddy
Application Serverতোমার Business Logic চালিয়ে Dynamic Response তৈরি করে3000, 8000, 8080 (Proxy-র পেছনে)Node.js, Spring Boot, Django, Tomcat
Database ServerData রাখে ও Query-র উত্তর দেয়5432 (PostgreSQL), 3306 (MySQL), 27017 (MongoDB)PostgreSQL, MySQL, MongoDB
Cache Serverএক Millisecond-এর কম সময়ে পড়ার জন্য গরম Data Memory-তে রাখে6379 (Redis), 11211 (Memcached)Redis, Memcached
DNS Serverনামকে IP Address-এ রূপান্তর করে53 UDP/TCPDNS Lesson দেখো
Mail ServerEmail পাঠায়, পৌঁছে দেয় ও জমা রাখেSMTP 25 (Server থেকে Server), 587 (Submission); IMAP 993; POP3 995Postfix, Microsoft Exchange, Gmail
File Serverশেয়ার করা File ও FolderSFTP 22, FTP 21, SMB 445, NFS 2049Samba, একটি NAS যন্ত্র
Object Storageবিশাল পরিসরে HTTPS-এর মাধ্যমে নাম দিয়ে পুরো File (“Object”)443AWS S3, Google Cloud Storage, Ceph
Proxy / Load Balancerঅন্য Server-এ Request পাঠায়, চাপ ভাগ করে, TLS শেষ করে80, 443Nginx, HAProxy, Cloud Load Balancer
Directory / Authenticationকেন্দ্রীয় User, Group, Password ও অনুমতিLDAP 389/636, Kerberos 88Active Directory (AD), Open-source LDAP Server
Time Serverঘড়ি মিলিয়ে রাখতে নির্ভুল সময়NTP 123 UDPpool.ntp.org, time.google.com
Game ServerMultiplayer Game-এর চূড়ান্ত (Authoritative) অবস্থাসাধারণত UDP, Game অনুযায়ী (Minecraft 25565 TCP)Dedicated Game Server
Media Streamingছোট ছোট টুকরোয় Video ও Audio443 (HTTPS-এ Segment)Video Platform, প্রায়ই CDN হয়ে
Message BrokerService-দের মধ্যে Message Queue করে, যাতে তারা Asynchronous-ভাবে কাজ করতে পারেKafka 9092, RabbitMQ 5672Kafka, RabbitMQ
Print ServerPrinter শেয়ার করে ও Print Job Queue করে631, 9100Linux ও Windows-এর Print Service

প্রতিটি এক লাইনে:

  • Web Server Browser-এর সঙ্গে HTTP-তে কথা বলে, আর Static File, TLS ও অনেক Connection ধরে রাখায় খুব দক্ষ। Application Server তোমার Code চালায়। এরা প্রায়ই আলাদা Program, সামনে থাকে Web Server। Nginx, Apache, Caddy, Tomcat, Gunicorn প্রমুখ ঠিক কীভাবে এই কাজ ভাগ করে, আর Web Server কীভাবে Request তোমার Code-এর হাতে দেয়, তা নিয়েই Web Server ও App Server Lesson।
  • Database Server হলো সত্যের একমাত্র উৎস (Source of Truth); State রাখে বলে এদের Scale করা সাধারণত সবচেয়ে কঠিন।
  • Cache Server গতির বিনিময়ে টাটকা ভাব কিছুটা ছাড়ে: Memory থেকে উত্তর দেয়, Miss হলে Database-এর কাছে যায়।
  • Mail Server SMTP দিয়ে Server থেকে Server-এ Email পৌঁছায়; তোমার Mail App সেটি পড়ে IMAP (বা পুরনো POP3) দিয়ে।
  • File Server (Windows Share-এর জন্য SMB, Linux-এর জন্য NFS, আদান-প্রদানের জন্য SFTP) আর Object Storage (সহজ, সস্তা, প্রায় সীমাহীন, কিন্তু জায়গায় বসে Edit করা যায় না) File রাখে।
  • Proxy ও Load Balancer অন্য Server-এর সামনে বসে; Forward ও Reverse Proxy আছে Firewall, Proxy ও VPN Lesson-এ।
  • Directory Server-এর কারণে একটিই Login অফিসের প্রতিটি কম্পিউটার ও App-এ কাজ করে।
  • Time Server শুনতে যতটা মনে হয় তার চেয়ে বেশি জরুরি: ঘড়ি সরে গেলে TLS Certificate, অনেক মেশিনের Log আর Login Token সব গোলমাল হয়ে যায়।
  • Message Broker দ্রুত একটি Service-কে ধীর কাজ (Email, Thumbnail, Report) Background Worker-এর হাতে দিতে দেয়।

#Server কোথায় থাকে

প্রতিটি Server শেষ পর্যন্ত কোনো একটি ভবনের Physical Hardware-এ চলে। তুমি বেছে নাও Stack-এর কতটা তোমার নিজের এবং তুমি সামলাবে।

#On-premises, Colocation ও Dedicated Server

  • On-premises: নিজের Server Room-এ নিজের Server। পূর্ণ নিয়ন্ত্রণ, কোনো ভাড়া নেই, কিন্তু সব খরচ আগেই দিতে হয়, আর বিদ্যুৎ, শীতলীকরণ, অতিরিক্ত যন্ত্রাংশ ও রাত ৩টার বিকলতা নিজেকেই সামলাতে হয়। ব্যাংক ও সরকার প্রায়ই সংবেদনশীল System এভাবে রাখে।
  • Colocation: Server তোমার, কিন্তু পেশাদার একটি Data Centre-এ Rack-এর জায়গা, বিদ্যুৎ, শীতলীকরণ ও Network ভাড়া নাও।
  • Dedicated / Bare-metal Server: Hosting কোম্পানি (Hetzner ও আরও অনেকে) বা Cloud-এর Bare-metal সেবা থেকে পুরো একটি Physical মেশিন ভাড়া নাও। পূর্ণ Performance, কোনো প্রতিবেশী নেই, কিন্তু আকার বদলাতে হলে অন্য মেশিনে সরতে হয়।

#Virtual Machine ও VPS

একটি Hypervisor (KVM, Xen, Microsoft Hyper-V, VMware) একটি Physical Server-কে অনেকগুলো আলাদা Virtual Machine (VM)-এ ভাগ করে, প্রত্যেকের নিজস্ব ভাগের CPU Core, RAM, Disk আর নিজস্ব অপারেটিং সিস্টেম। একটি VPS (Virtual Private Server: DigitalOcean, Linode, Vultr প্রমুখ থেকে) আর একটি AWS EC2 Instance দুটোই VM। প্রায় এক মিনিটে SSH দিয়ে Root Access পাও, আর ঘণ্টা বা সেকেন্ড হিসেবে টাকা দাও; নষ্ট Hardware বদলায় Provider, প্রায়ই তোমার VM অন্য Host-এ সরিয়ে দিয়ে। OS Patch ও Scaling তখনো তোমার কাজ।

একটি Hypervisor আসলে কীভাবে একটা মেশিনকে ভাগ করে দেয় (CPU Ring আর Hardware-এর সাহায্য, RAM আর Core-কে দরকারের চেয়ে বেশি বরাদ্দ দেওয়া, দুটি VM কীভাবে Virtual Switch দিয়ে কথা বলে), তা বিস্তারিত পাবে ৪ নম্বর অধ্যায়ে, Server, Virtualization ও Cloud-এ। আপাতত এটুকু মনে রাখো: তোমার Program-এর চোখে একটি VM মানেই “একটি Server”।

#Container

Container ছোট কোনো VM নয়। এটি একটি সাধারণ Process, যাকে Kernel আলাদা করে রাখে (Namespace ও cgroup দিয়ে), ফলে সে নিজের File, Network ও Process তালিকা দেখে আর CPU ও Memory-র নির্দিষ্ট ভাগ পায়। একটি মেশিনের সব Container Host-এর Kernel ভাগ করে নেয়, তাই Container প্রায় এক সেকেন্ডে চালু হয় আর তার Image Gigabyte নয়, Megabyte। Docker Container ব্যবহার সহজ করেছে: Image তোমার Program-কে ঠিক প্রয়োজনীয় Library-সহ বেঁধে দেয়, তাই Laptop-এ আর Production-এ একইভাবে চলে। Container সাধারণত VM-এর ভেতরে চলে।

যখন কয়েক ডজন মেশিনে শত শত Container, তখন একটি Orchestrator ঠিক করে কোনটি কোথায় চলবে। Kubernetes হলো Standard: তুমি ঘোষণা করো “এই Image-এর ৬টি কপি চালাও, প্রতিটি ১ CPU ও ৫১২ MB নিয়ে”, আর সে সেগুলো বসায়, Crash করলে আবার চালু করে, মরে যাওয়া মেশিন বদলায়, Rolling Update করে। প্রতিটি Cloud-এ Managed সংস্করণ আছে, কারণ নিজে Kubernetes চালানো রীতিমতো খাটুনির কাজ।

#Serverless (Function as a Service)

Serverless Computing-এ (AWS Lambda, Google Cloud Functions, Azure Functions) তুমি একটি Function Upload করো, আর প্রতিটি Event-এ Provider তার একটি কপি চালায়: একটি HTTP Request, একটি File Upload, একটি Queue Message। কোনো মেশিন তুমি কখনো দেখো না। এটি নিজে নিজেই শূন্য থেকে হাজারো কপিতে Scale করে, আর তুমি টাকা দাও প্রতি Request ও প্রতি Millisecond হিসেবে, অলস থাকলে কিছুই না।

নামটি বিভ্রান্তিকর: Server এখনো আছে, শুধু সেগুলো তোমার মাথাব্যথা নয়। Trade-off-গুলো বাস্তব:

  • Cold Start: চালু কোনো কপি না থাকলে Provider-কে আগে নতুন একটি Environment চালু করতে হয়, এতে প্রায় ১০০ ms থেকে এক সেকেন্ডেরও বেশি যোগ হয়।
  • সীমা: একটি Lambda Invocation সর্বোচ্চ ১৫ মিনিট চলতে পারে, আর দুই Call-এর মাঝে Memory-র কিছু টিকে থাকবে এমন নিশ্চয়তা নেই, তাই State রাখতে হয় Database বা Cache-এ।
  • বড় পরিসরে খরচ: স্থির ও ভারী Traffic-এ প্রায়ই একঝাঁক VM সস্তা পড়ে।

#Edge

Edge Computing ছোট ছোট Code চালায় CDN-এর Point of Presence-এ, ব্যবহারকারীর শারীরিকভাবে কাছে: Cloudflare Workers, CloudFront Functions, Lambda@Edge। Redirect, Authentication যাচাই, A/B Test আর Cache করা Page ব্যক্তিগতকরণের জন্য ভালো, ব্যবহারকারী থেকে কয়েক Millisecond দূরে; ভারী কাজ বা মূল Database লাগে এমন কিছুর জন্য নয়।

তোমার Code কোথায় চলে, আর প্রতিটি স্তর কে দেখে

প্রতিটি বিকল্পই শেষ পর্যন্ত Data Centre-এর একটি Physical Server-এ চলে। পার্থক্য শুধু কতগুলো স্তর তুমি নিজে সামলাও।

পরিস্থিতি

পুরো মেশিন তোমার নিজের বা ভাড়া করা।

Data Centreভবন, বিদ্যুৎ, শীতলীকরণ, Network
ধাপ 1 / 4
1

বিদ্যুৎ, শীতলীকরণ ও Network-সহ একটি ভবন। তোমার নিজের Server Room (On-premises), অথবা অন্যের ভবনে ভাড়া নেওয়া Rack (Colocation)।

#IaaS, PaaS, SaaS, FaaS: কে কী সামলায়

তুমি সামলাও ↓ / Model →On-premisesIaaS (EC2, Compute Engine)PaaS (Heroku, App Engine, Elastic Beanstalk)FaaS (Lambda, Cloud Functions)SaaS (Gmail, Salesforce)
ভবন, বিদ্যুৎ, NetworkতুমিProviderProviderProviderProvider
Physical Server, StorageতুমিProviderProviderProviderProvider
VirtualisationতুমিProviderProviderProviderProvider
অপারেটিং সিস্টেম, PatchতুমিতুমিProviderProviderProvider
Runtime (Node.js, Java…)তুমিতুমিProviderProviderProvider
Scalingতুমিতুমি (Tool-সহ)বেশিরভাগ ProviderProviderProvider
Application Codeতুমিতুমিতুমিতুমি (শুধু Function)Provider
Data ও ব্যবহারকারীতুমিতুমিতুমিতুমিতুমি

#Scaling ও Reliability-র মূল কথা

#Vertical বনাম Horizontal Scaling

Vertical Scaling (Scale Up)Horizontal Scaling (Scale Out)

আরও বড় মেশিন কেনো: বেশি Core, বেশি RAM, দ্রুত Disk।

  • সহজ: Code বদলাতে হয় না, একটি মেশিন সামলাতে হয়।
  • একটি ছাদ আছে: টাকায় কেনা যায় এমন সবচেয়ে বড় মেশিন।
  • তখনো Single Point of Failure, আর আকার বদলাতে সাধারণত Restart লাগে।
  • একটা সীমা পর্যন্ত Database-এর জন্য ভালো।

আরও মেশিন যোগ করো, আর একটি Load Balancer দিয়ে তাদের মধ্যে চাপ ভাগ করো।

  • প্রায় কোনো ছাদ নেই; কয়েক মিনিটে Capacity বাড়ানো যায়।
  • একটি মেশিন হারালেও টিকে থাকে।
  • Stateless Server লাগে: যেকোনো Server যেকোনো Request-এর উত্তর দিতে পারবে।
  • Web ও App Server Scale করার স্বাভাবিক পদ্ধতি।

Horizontal Scaling তখনই কাজ করে যখন Server ব্যবহারকারীর Session নিজের Memory-তে রাখে না; নইলে পরের Request এমন Server-এ পড়ে যে ব্যবহারকারীকে চেনে না। সেই State কোথায় থাকা উচিত (শেয়ার করা Cache, Database, বা Sign করা Token) তা নিয়েই পরের Lesson: State, Cookie ও Session।

#Load Balancer, Health Check ও Single Point of Failure

Load Balancer হলো সেই একটি Address যেখানে Client Connect করে; সে একঝাঁক একই রকম Server-এর মধ্যে Request ভাগ করে দেয়। সে Health Check-ও চালায়: প্রতি কয়েক সেকেন্ডে প্রতিটি Server-এ GET /health-এর মতো কিছু Call করে, আর পরপর কয়েকবার ব্যর্থ হলে সেই Server সেরে না ওঠা পর্যন্ত তাকে Traffic পাঠানো বন্ধ রাখে। ভালো Health Endpoint সস্তা, আর শুধু Process বেঁচে আছে কি না নয়, আসলে সেবা দিতে পারছে কি না তা যাচাই করে।

Single Point of Failure (SPOF) হলো এমন যেকোনো অংশ, যা নষ্ট হলে পুরো System বন্ধ হয়ে যায়: একটি Server, একটি Database, একটি Load Balancer, একটি Power Feed, একটি DNS Provider, একটি Region। High Availability (HA) মানে প্রতিটি SPOF খুঁজে তার জোড়া রাখা; এজন্যই Load Balancer নিজেও জোড়ায় চলে আর Database-এর Replica থাকে।

#“Nines”-এ Availability

Availability হলো একটি সেবা কত শতাংশ সময় কাজ করে। প্রতিটি বাড়তি ৯ অনুমোদিত Downtime দশ ভাগের এক ভাগে নামিয়ে আনে:

Availabilityবছরে Downtimeমাসে (৩০ দিন)মোটামুটি মানে
৯৯% (“Two Nines”)৩.৬৫ দিন৭.২ ঘণ্টাএকটি Server, হাতে ঠিক করা হয়
৯৯.৯% (“Three Nines”)৮.৭৬ ঘণ্টা৪৩.২ মিনিটRedundant Server, মোটামুটি ভালো Monitoring
৯৯.৯৯% (“Four Nines”)৫২.৬ মিনিট৪.৩ মিনিটকোনো SPOF নেই, স্বয়ংক্রিয় Failover, সতর্ক Deploy
৯৯.৯৯৯% (“Five Nines”)৫.২৬ মিনিট২৬ সেকেন্ডএকাধিক Region, খুব ব্যয়বহুল Engineering

একটি শৃঙ্খলে থাকা অংশগুলোর Availability গুণ হয়: ৯৯.৯% একটি App যদি ৯৯.৯% একটি Database-এর ওপর নির্ভর করে, তাহলে সর্বোচ্চ প্রায় ৯৯.৮%। সমান্তরালে জোড়া রাখলে উল্টোটা ঘটে: ৯৯% করে দুটি স্বাধীন Server একসঙ্গে বন্ধ থাকে মাত্র ০.০১% সময়।

তিনটি শব্দ শুনবে:

  • SLI (Service Level Indicator): যা তুমি মাপো, যেমন “কত শতাংশ Request ৩০০ ms-এর মধ্যে সফল হয়”।
  • SLO (Service Level Objective): তার জন্য তোমার অভ্যন্তরীণ লক্ষ্য, যেমন “৩০ দিনে ৯৯.৯৫%”।
  • SLA (Service Level Agreement): গ্রাহকের চুক্তিতে লেখা প্রতিশ্রুতি, সাধারণত SLO-র চেয়ে ঢিলা, ভাঙলে টাকা ফেরত।

#কী ভুল হয়, আর কীভাবে টের পাও

Server অল্প কয়েকটি পরিচিত উপায়ে বারবার ব্যর্থ হয়। এগুলো চিনতে শেখো:

সমস্যালক্ষণসাধারণ সমাধান
Process Crash (Unhandled Error)Proxy থেকে 502, Connection Refused, Log-এ RestartSupervisor আবার চালু করে; Stack Trace দেখে Bug ঠিক করো
Crash Loop (ভুল Config, Secret নেই)কয়েক সেকেন্ড পরপর Restart, কখনো সুস্থ হয় না (Kubernetes-এ CrashLoopBackOff)Startup Log পড়ো; Restart-এ কাজ হবে না
Memory শেষExit Code 137 দিয়ে Process মারা যায়, dmesg-এ oom-kill, করাতের দাঁতের মতো Memory GraphLeak খুঁজে বের করো; Memory Limit দাও; RAM বাড়াও
Disk ভর্তি (প্রায়ই Log)Write ব্যর্থ, Database Commit করতে অস্বীকার করে, সবখানে অদ্ভুত ErrorLog Rotation, ৮০%-এ Alert, পরিষ্কার করো; df -h, du -sh
Too many open filesEMFILE Error, চাপের সময় নতুন Connection প্রত্যাখ্যাতDescriptor সীমা বাড়াও; Descriptor Leak খোঁজো
CPU ১০০%সবার Latency বাড়ে; Load Average Core-সংখ্যার অনেক ওপরেProfile করো; ভারী কাজ Request-এর পথ থেকে সরাও; Scale Out
ধীর DependencyRequest জমে, Pool ফুরায়, Timeout, 504প্রতিটি Call-এ Timeout, Circuit Breaker, Cache
খারাপ DeployRelease-এর ঠিক পরেই Error Rate লাফিয়ে ওঠেআগে Rollback, পরে তদন্ত

Server Process যখন মারা যায়, আর যখন ইচ্ছে করে বদলাও

Supervisor Crash করা Process আবার চালু করে; সতর্ক Deploy আগে Connection Drain করে, যাতে কেউ টের না পায়।

পরিস্থিতি

ব্যবহারকারী
Load Balancer
Server Process:8080
OS + systemdSupervisor
GET /orders
ধাপ 1 / 7
1

স্বাভাবিক Traffic।

#Graceful Shutdown ও Connection Draining

প্রতিটি Deploy চলমান Server Process বদলে দেয়। অসাবধানে করলে Request মাঝপথে কেটে যায়। সতর্ক ধাপগুলো:

  1. Load Balancer-কে বলো এই Server-এ নতুন Request পাঠানো বন্ধ করতে (Draining বা Deregistration; AWS Load Balancer চলমান Request-এর জন্য Default-এ ৩০০ সেকেন্ড পর্যন্ত অপেক্ষা করে)।
  2. Process-কে SIGTERM পাঠাও। সে নতুন Accept বন্ধ করে, চলমান Request শেষ করে, Database Connection বন্ধ করে, তারপর বের হয়।
  3. নির্দিষ্ট সময় (Kubernetes-এ Default ৩০ সেকেন্ড) পরেও চলতে থাকলে সে পায় SIGKILL।
  4. নতুন Version চালু করো, Health Check পাস করা পর্যন্ত অপেক্ষা করো, তারপরই Traffic পাঠাও। Server ধরে ধরে পুনরাবৃত্তি করো: একেই বলে Rolling Deploy।

#Monitoring: চারটি Golden Signal

Google-এর Site Reliability Engineering (SRE) বই প্রতিটি সেবার জন্য চারটি সংখ্যা নজরে রাখতে বলে:

  • Latency: Request-এ কত সময় লাগে, সফল ও ব্যর্থ আলাদা করে (দ্রুত Error মানে দ্রুত সাফল্য নয়)। ৯৯তম Percentile দেখো।
  • Traffic: চাহিদা কতটা: প্রতি সেকেন্ডে Request, Connection, Byte।
  • Errors: ব্যর্থ Request-এর হার (5xx, Timeout, ভুল উত্তর)।
  • Saturation: Server কতটা ভর্তি: CPU, Memory, Disk, Pool-এর ব্যবহার, Queue-এর দৈর্ঘ্য। Latency ও Error বাড়ার আগেই Saturation সতর্ক করে।

Linux-এ uptime ও top দেখায় Load Average: ১, ৫ ও ১৫ মিনিটে গড়ে কতগুলো Process চলছে বা চলার অপেক্ষায় আছে (Disk-এর অপেক্ষায় আটকে থাকা Process-সহ)। Core-সংখ্যার সঙ্গে তুলনা করো: ৮ Core-এর মেশিনে Load ৮ মানে পুরো ব্যস্ত; ৮ Core-এ ৩০ মানে কাজ Queue-তে জমছে।

#System Design-এ Server

Design Interview-এ প্রায় প্রতিটি উত্তরেই Server আসে। কয়েকটি অভ্যাস তোমাকে অভিজ্ঞ শোনাবে:

  • ভূমিকাগুলো আলাদা করো। Load Balancer, Stateless App Server, Cache, Database, Object Storage আর Background Worker আলাদা বাক্সে আঁকো, কারণ এরা ভিন্নভাবে Scale করে আর ভিন্নভাবে ব্যর্থ হয়।
  • App Server Stateless রাখো, যাতে ইচ্ছেমতো যোগ-বিয়োগ করা যায়; State রাখো Database, Cache বা Object Storage-এ।
  • Capacity-র হিসাব করো। “দিনে ১ কোটি Request মানে গড়ে প্রতি সেকেন্ডে প্রায় ১১৫টি, Peak-এ হয়তো ৫ গুণ, তাই প্রায় ৬০০। আমাদের Latency-তে একটি Server ৩০০ সামলালে লাগবে ২টি, তাই Redundancy-র জন্য অন্তত ৩টি চালাই।” Connection ও Thread-এর সংখ্যার জন্য Little’s Law ব্যবহার করো।
  • দরকার হলে Concurrency Model-এর নাম বলো: ধীর Client সামলাতে সামনে একটি Event-driven Proxy; পেছনের Database Pool অনুযায়ী Thread Pool-এর আকার।
  • SPOF সরাও এবং বলো প্রতিটি বাক্স মরে গেলে কী হয়: Health Check, Replica, একাধিক Availability Zone।
  • কোথায় চলবে তা বেছে নাও, কারণসহ: হঠাৎ ওঠানামা করা, কম বা অনিশ্চিত Traffic-এ Serverless; অনেক Service ও স্থির চাপে Kubernetes-এ Container; সহজ, নির্দিষ্ট কাজে VM; চরম Performance বা বড় পরিসরে খরচ বাঁচাতে Bare Metal।
  • Operations-এর কথা বলো: প্রতিটি বাইরের Call-এ Timeout, Graceful Shutdown, Golden Signal আর একটি SLO।

#নিজে করে দেখো

১. এক লাইনে তোমার কম্পিউটারকে Web Server বানাও। Python-এর সঙ্গে একটি ছোট্ট File Server আসে। যেকোনো Folder-এ:

python -m http.server 8000                  # সব Address-এ বর্তমান Folder পরিবেশন করে
python -m http.server 8000 --bind 127.0.0.1 # এবার শুধু এই কম্পিউটারই পৌঁছাতে পারবে

Browser-এ http://localhost:8000 খোলো। তারপর তোমার LAN Address বের করো (Windows-এ ipconfig, Linux-এ ip addr, macOS-এ ipconfig getifaddr en0) এবং একই Wi-Fi-তে থাকা ফোন থেকে http://<সেই-address>:8000 খোলো। প্রথম Command-এ কাজ করবে (Windows হয়তো Firewall-এ Python-কে অনুমতি দিতে বলবে); --bind 127.0.0.1 দিলে ফোন Error পাবে। তুমি এইমাত্র “আমার মেশিনে চলে” Bug-টি নিজে ঘটালে।

২. curl দিয়ে কথোপকথন দেখো:

curl -v http://localhost:8000/          # Connect, Request আর Response Header দেখো
curl -v http://localhost:8001/          # 8001-এ কেউ Listen করছে না: সঙ্গে সঙ্গে "Connection refused"

৩. নিজে একটি Server লেখো। server.js নামে Save করে node server.js চালাও:

const http = require('node:http');

let count = 0;
const server = http.createServer((req, res) => {
  count += 1;
  console.log(`${new Date().toISOString()} ${req.method} ${req.url}`); // Access Log
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ hello: 'world', path: req.url, requestNumber: count }));
});

server.listen(8080, '0.0.0.0', () => console.log('listening on :8080'));

// Graceful Shutdown: নতুন Accept বন্ধ, চলমান Request শেষ, তারপর বের হওয়া।
process.on('SIGTERM', () => server.close(() => process.exit(0)));

অন্য একটি Terminal-এ দ্বিতীয়বার চালু করলে পাবে EADDRINUSE। এরপর Handler-এর শুরুতে একটি Busy Loop যোগ করো, const end = Date.now() + 3000; while (Date.now() < end) {}, আবার চালু করো, আর দুটি Tab-এ একসঙ্গে Page খোলো: দ্বিতীয় Tab প্রথমটির জন্য অপেক্ষা করবে, কারণ তুমি Event Loop আটকে দিয়েছ।

৪. কোন কোন Program Listen করছে দেখো:

# Linux
ss -tlnp                       # t=TCP, l=listening, n=numeric, p=process
# macOS
lsof -iTCP -sTCP:LISTEN -n -P
# Windows
netstat -ano | findstr LISTENING
Get-NetTCPConnection -State Listen | Sort-Object LocalPort

Local Address কলামটি দেখো: 0.0.0.0:8080 বা [::]:8080 Network থেকে পৌঁছানো যায়, 127.0.0.1:8080 শুধু এই মেশিন থেকে।

৫. সবচেয়ে সরল Server। Netcat একটি Port-এ Listen করে, যা আসে তা Print করে:

nc -l 9000          # macOS / আধুনিক Linux (পুরনো netcat-এ: nc -l -p 9000)
# অন্য একটি Terminal-এ:
curl http://localhost:9000/hello

প্রথম Terminal-এ curl-এর কাঁচা HTTP Request দেখতে পাবে। হাতে একটি উত্তর লিখে Ctrl+C চাপো: এতক্ষণ তুমিই ছিলে Server।

৬. Resource দেখো। একটি Loop-এ Server-কে Request পাঠাতে থাকো (for i in $(seq 1000); do curl -s localhost:8080 > /dev/null; done), আর তখন htop (Linux/macOS) চালাও বা Task Manager → Performance (Windows) খোলো। প্রতি Core-এর CPU, Memory আর Process তালিকা লক্ষ করো।

#সারসংক্ষেপ

মূল শিক্ষা

  • Server একটি ভূমিকা: এমন Program যে Request-এর অপেক্ষা করে ও উত্তর দেয়, আর সেই সূত্রে যে কম্পিউটারে সে চলে। যেকোনো মেশিন Server হতে পারে, আর একটি Server প্রায়ই অন্য Server-এর Client।
  • Server Program হলো দীর্ঘক্ষণ চলা Process, যাকে একটি Service Manager চালু ও পুনরায় চালু করে। সে socket → bind → listen → accept Call করে, তারপর প্রতিটি Request পড়ে, প্রক্রিয়া করে, লেখে ও Log করে।
  • Bind Address ঠিক করে কে Connect করতে পারবে: 127.0.0.1 শুধু Local, 0.0.0.0 / :: সবার জন্য। Refused মানে কেউ Listen করছে না; Timeout মানে কিছু একটা Packet ফেলে দিচ্ছে; EADDRINUSE মানে Port দখল হয়ে আছে।
  • প্রতিটি Request খরচ করে CPU, Memory, I/O, একটি File Descriptor ও Pool-এর Connection; এর যেকোনোটিই ফুরিয়ে যেতে পারে।
  • Concurrency Model: প্রতি Connection-এ Process, প্রতি Connection-এ Thread / Pool, epoll/kqueue/IOCP-সহ Event Loop, আর প্রতি Core-এ একটি Event Loop। Thread-এর বিপদ Pool Exhaustion; Event Loop কখনো Block হতে পারবে না।
  • অতিরিক্ত চাপ দেখা দেয় প্রথমে বাড়তে থাকা Latency, তারপর Timeout, তারপর Error হিসেবে। Little’s Law: চলমান Request = আসার হার × প্রতি Request-এর সময়।
  • Server Hardware ২৪ ঘণ্টা কাজ ও চলন্ত অবস্থায় মেরামতের জন্য তৈরি: অনেক Core, ECC RAM, RAID, Redundant PSU ও NIC, আর দূর থেকে Power নিয়ন্ত্রণের জন্য BMC। বেশিরভাগ Server চলে SSH দিয়ে পরিচালিত Headless Linux-এ।
  • Server-এর নাম হয় সে কী পরিবেশন করে তা দিয়ে (Web, App, Database, Cache, DNS, Mail, File, Object Storage, Proxy, Directory, Time, Broker…), প্রত্যেকের পরিচিত Port আছে।
  • Server চলে Bare Metal, VM, Container বা Serverless Function-এ; IaaS → PaaS → FaaS → SaaS ক্রমে আরও বেশি স্তর Provider-এর হাতে যায়।
  • Health Check-ওয়ালা Load Balancer-এর পেছনে Stateless Server দিয়ে Scale Out করো, SPOF সরাও, Golden Signal দিয়ে মাপো, আর Draining ও Graceful Shutdown দিয়ে Deploy করো।