وقتی یک Application از یک Server فراتر میرود، یکی از اولین چالشهای زیرساختی این است که چگونه Traffic کاربران را بین چند Server یا چند Instance توزیع کنیم؛ به شکلی که هم Performance حفظ شود، هم در صورت خرابی یک Server سرویس همچنان در دسترس بماند و هم بتوان ظرفیت سیستم را با اضافه کردن Backendهای بیشتر افزایش داد.
اینجاست که Load Balancer وارد معماری میشود.
Load Balancer در سادهترین تعریف، ترافیک ورودی را دریافت و آن را بر اساس یک الگوریتم مشخص بین چند Backend توزیع میکند. اما در معماریهای Production، وظیفه آن معمولاً بسیار فراتر از توزیع ساده Requestهاست و میتواند شامل Health Check، TLS Termination، Reverse Proxy، Connection Management، Session Persistence، Rate Limiting، Routing، Failover و Observability نیز باشد.
ابزارهای مختلفی برای این کار وجود دارند؛ از Nginx و HAProxy گرفته تا Envoy و Load Balancerهای Cloud. انتخاب ابزار مناسب نیز به نوع Traffic، Layer مورد نیاز، تعداد Backendها، نیازهای High Availability، پیچیدگی Routing و نحوه مدیریت زیرساخت بستگی دارد.
در این مقاله ابتدا مفهوم Load Balancing را بررسی میکنیم، سپس به Layer 4 و Layer 7، الگوریتمهای مختلف، Health Check، Sticky Session، TLS، High Availability و معماریهای رایج میپردازیم و در ادامه Nginx، HAProxy و گزینههای دیگر را با یکدیگر مقایسه میکنیم.
Load Balancer چیست؟
فرض کنید یک Application روی سه Server اجرا میشود:
Users
│
▼
Load Balancer
/ | \
/ | \
▼ ▼ ▼
Server 1 Server 2 Server 3
کاربر معمولاً مستقیماً با Backendها ارتباط ندارد. درخواست ابتدا به Load Balancer میرسد و Load Balancer تصمیم میگیرد درخواست یا Connection به کدام Backend ارسال شود.
هدف اصلی این معماری میتواند شامل موارد زیر باشد:
- توزیع بار بین چند Server
- افزایش ظرفیت سرویس
- کاهش اثر خرابی یک Backend
- افزایش Availability
- مدیریت Connectionهای ورودی
- SSL/TLS Termination
- Routing بر اساس Host یا URL
- Health Check
- ایجاد یک نقطه کنترل برای Traffic
NGINX نیز Load Balancing را روشی برای بهبود استفاده از منابع، افزایش Throughput، کاهش Latency و ایجاد Fault-Tolerant Configuration معرفی میکند.
چرا به Load Balancer نیاز داریم؟
در یک معماری Single Server، تمام Traffic به یک سیستم ارسال میشود:
Internet
│
▼
Server
│
├── Application
├── Database
└── Storage
این معماری ساده است، اما یک مشکل مهم دارد: Single Point of Failure.
اگر Server از کار بیفتد، Application نیز از دسترس خارج میشود.
با اضافه کردن Backendهای متعدد:
Internet
│
▼
Load Balancer
/ | \
▼ ▼ ▼
App-1 App-2 App-3
میتوان Traffic را بین چند Instance تقسیم کرد و در صورت خرابی یکی از آنها، Traffic را به Backendهای سالم ارسال کرد.
Load Balancing و Scalability
Load Balancer یکی از اجزای مهم معماری Horizontal Scaling است.
به جای اینکه یک Server را دائماً بزرگتر کنیم، میتوان تعداد Instanceها را افزایش داد:
2 Servers
↓
4 Servers
↓
8 Servers
↓
20 Servers
Load Balancer در این میان نقش توزیع Traffic را بر عهده دارد.
البته Load Balancer بهتنهایی مشکل Scalability را حل نمیکند. Database، Cache، Storage، Session و سایر Dependencyها نیز باید بتوانند با افزایش Traffic مقیاسپذیر باشند.
انواع Load Balancing بر اساس Layer
یکی از مهمترین مفاهیم در انتخاب Load Balancer، تفاوت بین Layer 4 و Layer 7 است.
Layer 4 Load Balancing
Layer 4 در مدل OSI مربوط به Transport Layer است و معمولاً با Protocolهایی مانند TCP و UDP سروکار دارد.
در L4، Load Balancer معمولاً بدون نیاز به درک محتوای HTTP Request، Connection یا Packet را به Backend مناسب منتقل میکند.
Client
│
│ TCP
▼
L4 Load Balancer
│
├── TCP → Backend 1
├── TCP → Backend 2
└── TCP → Backend 3
مزایای معمول L4 عبارتاند از:
- Overhead کمتر
- Performance بالا
- مناسب برای TCP/UDP
- قابل استفاده برای Protocolهای غیر HTTP
- مناسب برای برخی سناریوهای High Throughput
NGINX Open Source نیز میتواند در Layer 4 برای TCP و UDP Proxying و Load Balancing استفاده شود.
Layer 7 Load Balancing
در Layer 7، Load Balancer اطلاعات Application Protocol را میبیند. برای HTTP/HTTPS میتوان بر اساس اطلاعاتی مانند:
- Hostname
- URL Path
- HTTP Header
- Cookie
- Method
- Application-level information
تصمیم Routing گرفت.
برای مثال:
example.com/api/*
│
▼
API Pool
example.com/images/*
│
▼
Image Pool
admin.example.com
│
▼
Admin Pool
این یکی از مهمترین مزایای L7 است: Load Balancer میتواند علاوه بر توزیع بار، بخشی از منطق Traffic Routing را نیز انجام دهد.
مقایسه Layer 4 و Layer 7
| ویژگی | Layer 4 | Layer 7 |
|---|---|---|
| سطح تصمیمگیری | Transport | Application |
| Protocolهای رایج | TCP / UDP | HTTP / HTTPS |
| مشاهده URL | خیر | بله |
| Routing بر اساس Host | معمولاً خیر | بله |
| TLS Termination | معمولاً انجام نمیشود | قابل انجام است |
| Application-aware Routing | محدود | بالا |
| Overhead | کمتر | بیشتر |
| Protocolهای غیر HTTP | مناسب | محدود به قابلیت ابزار |
الگوریتمهای Load Balancing
Load Balancer باید برای هر Request یا Connection تصمیم بگیرد که آن را به کدام Backend ارسال کند. این تصمیم میتواند بر اساس الگوریتمهای مختلف انجام شود.
Round Robin
سادهترین الگوریتم، Round Robin است.
در این روش Requestها به صورت چرخشی بین Backendها توزیع میشوند:
Request 1 → Server 1
Request 2 → Server 2
Request 3 → Server 3
Request 4 → Server 1
Request 5 → Server 2
Request 6 → Server 3
Round Robin زمانی مناسب است که Backendها تقریباً ظرفیت مشابهی داشته باشند و Requestها نیز از نظر مدت زمان پردازش تفاوت زیادی نداشته باشند.
Round Robin روش پیشفرض NGINX در بسیاری از سناریوهای Upstream است.
Weighted Round Robin
اگر Backendها ظرفیت یکسانی نداشته باشند، میتوان برای آنها Weight تعریف کرد.
Server 1 → Weight 3
Server 2 → Weight 1
در این حالت Server اول سهم بیشتری از Traffic دریافت میکند.
این روش برای زمانی مناسب است که مثلاً یک Server دارای CPU یا RAM بیشتری از Server دیگر باشد.
Least Connections
در روش Least Connections درخواست جدید به Backendی ارسال میشود که تعداد Connection فعال کمتری دارد.
Server 1 → 120 connections
Server 2 → 45 connections
Server 3 → 80 connections
New Request → Server 2
این الگوریتم برای Applicationهایی که Requestها مدت زمان پردازش متفاوتی دارند میتواند مناسبتر از Round Robin باشد.
هم NGINX و هم HAProxy از مدلهای مبتنی بر تعداد Connection پشتیبانی میکنند.
Least Time / Least Latency
در این مدل، Load Balancer علاوه بر تعداد Connectionها، زمان پاسخ Backendها را نیز در تصمیمگیری در نظر میگیرد.
در NGINX، Least Time میتواند بر اساس زمان دریافت Header یا دریافت کامل Response سنجیده شود.
این روش زمانی جذاب است که Performance Backendها یکسان نباشد و برخی Serverها در عمل Response Time بهتری داشته باشند.
IP Hash
در IP Hash، انتخاب Backend بر اساس IP Client انجام میشود.
در نتیجه درخواستهای یک Client معمولاً به یک Backend مشخص هدایت میشوند.
این روش میتواند برای Sessionهای Local مفید باشد، اما یک راهحل ایدهآل برای Session Management نیست؛ زیرا تغییر IP کاربران، NAT و توزیع نامتوازن Clientها میتواند روی توزیع بار اثر بگذارد.
NGINX از IP Hash پشتیبانی میکند و HAProxy نیز روشهای مختلفی برای Persistence و Hash-based Distribution ارائه میدهد.
Consistent Hashing
در Consistent Hashing، هدف این است که با اضافه یا حذف شدن Backendها، کمترین تعداد Keyها مجدداً Map شوند.
این روش برای سناریوهایی مانند Cache یا سرویسهایی که داده بر اساس Key توزیع میشود اهمیت زیادی دارد.
برای مثال:
Cache Key
│
▼
Hash Function
│
├── Node 1
├── Node 2
└── Node 3
NGINX در Generic Hash امکان استفاده از Consistent Hashing را ارائه میکند و Envoy نیز سیاستهایی مانند Ring Hash و Maglev را پشتیبانی میکند.
Health Check چیست و چرا حیاتی است؟
فرض کنید سه Backend داریم:
Backend 1 → Healthy
Backend 2 → Healthy
Backend 3 → DOWN
اگر Load Balancer از وضعیت Backend سوم خبر نداشته باشد، همچنان ممکن است Traffic را به آن ارسال کند.
به همین دلیل Health Check یکی از مهمترین قابلیتهای Load Balancer است.
Passive Health Check
در Passive Health Check، Load Balancer از نتیجه واقعی Requestها متوجه مشکل Backend میشود.
برای مثال اگر Connectionهای متعددی به یک Server با خطا مواجه شوند، Load Balancer میتواند آن Backend را موقتاً از Rotation خارج کند.
NGINX Open Source در Reverse Proxy خود Passive/In-band Health Checking را ارائه میکند.
Active Health Check
در Active Health Check، Load Balancer به صورت مستقل یک درخواست یا Connection آزمایشی به Backend ارسال میکند.
برای مثال:
GET /health HTTP/1.1
Expected:
HTTP 200
اگر Backend پاسخ مورد انتظار را ندهد، از Rotation خارج میشود.
HAProxy از Active Health Check برای TCP و HTTP و همچنین Health Checkهای تخصصی برای برخی سرویسها پشتیبانی میکند.
برای Applicationهای جدی، Health Endpoint بهتر است صرفاً بررسی کند که Process زنده است یا نه؛ بلکه در صورت نیاز باید وضعیت Dependencyهای حیاتی نیز با دقت طراحی شود.
Health Check سطحی یا عمیق؟
دو Endpoint فرضی را در نظر بگیرید:
/health
→ Process is alive
/ready
→ Process + Database + Critical Dependencies are ready
استفاده از Health Check مناسب به معماری Application بستگی دارد.
اگر فقط Process را بررسی کنیم، ممکن است Application از نظر Process زنده باشد اما به Database دسترسی نداشته باشد.
از طرف دیگر، Health Check بیش از حد عمیق میتواند خودش فشار زیادی به Dependencyها وارد کند.
بنابراین باید بین Liveness، Readiness و Health واقعی سرویس تفکیک ایجاد کرد.
Session Persistence یا Sticky Session چیست؟
در معماری Stateless، هر Backend میتواند درخواست هر Client را پردازش کند.
اما اگر Session کاربر روی Local Memory یک Server نگهداری شود، ممکن است مشکل ایجاد شود:
Request 1 → Server 1
Request 2 → Server 2
Session موجود نیست!
برای حل این مشکل چند راه وجود دارد:
- Sticky Session
- Shared Session Store
- Redis
- Database-backed Session
- Stateless Authentication مانند Token
Sticky Session میتواند مشکل را کاهش دهد، اما در بسیاری از معماریهای مدرن بهتر است Application تا حد امکان Stateless طراحی شود و State در یک Storage مناسب نگهداری شود.
TLS Termination در Load Balancer
یکی از کاربردهای مهم Load Balancerهای Layer 7، Terminate کردن TLS است.
Client
│
│ HTTPS
▼
Load Balancer
│
│ HTTP / HTTPS
▼
Backend
در این مدل، TLS در Load Balancer Terminate میشود و Backend میتواند HTTP یا HTTPS دریافت کند.
مزایای این معماری:
- مدیریت متمرکز Certificateها
- کاهش پیچیدگی Backendها
- امکان Routing بر اساس HTTP
- متمرکز شدن برخی Security Policyها
در محیطهای حساس، ممکن است ارتباط Load Balancer تا Backend نیز با TLS ادامه پیدا کند:
Client
│ HTTPS
▼
Load Balancer
│ HTTPS
▼
Backend
این مدل معمولاً با عنوان TLS Re-encryption یا TLS بین Proxy و Upstream شناخته میشود.
Reverse Proxy و Load Balancer چه تفاوتی دارند؟
این دو مفهوم بسیار به هم نزدیکاند، اما دقیقاً یکسان نیستند.
Reverse Proxy واسطی بین Client و Backend است و میتواند وظایفی مانند TLS Termination، Routing، Header Manipulation و Caching را انجام دهد.
Load Balancer بر توزیع Traffic بین چند Backend تمرکز دارد.
یک ابزار مانند NGINX میتواند هر دو نقش را همزمان ایفا کند:
Internet
│
▼
NGINX
│
├── TLS Termination
├── Routing
├── Load Balancing
└── Proxy
│
┌───┼───┐
▼ ▼ ▼
App App App
برای آشنایی بیشتر با مفهوم Reverse Proxy میتوانید مقاله Reverse Proxy چیست؟ را مطالعه کنید.
NGINX چیست و چرا برای Load Balancing محبوب است؟
NGINX یکی از شناختهشدهترین Web Serverها و Reverse Proxyهای دنیا است و در معماریهای Load Balancing نیز کاربرد گستردهای دارد.
NGINX میتواند در Layer 7 برای HTTP/HTTPS و در Layer 4 برای TCP/UDP مورد استفاده قرار گیرد.
برخی قابلیتهای مهم آن عبارتاند از:
- Reverse Proxy
- HTTP Load Balancing
- TCP/UDP Load Balancing
- TLS Termination
- Round Robin
- Least Connections
- IP Hash
- Generic Hash
- Least Time
- Connection Management
- Static Content Serving
نمونه Load Balancing با NGINX
یک Configuration ساده میتواند به شکل زیر باشد:
http {
upstream backend {
server app1:8080;
server app2:8080;
server app3:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
در این Configuration، NGINX درخواستها را بین سه Backend توزیع میکند.
Least Connections در NGINX
upstream backend {
least_conn;
server app1:8080;
server app2:8080;
server app3:8080;
}
این مدل میتواند برای Workloadهایی که Connectionها مدت زمان متفاوتی دارند مناسبتر باشد.
Weighted Load Balancing در NGINX
upstream backend {
server app1:8080 weight=5;
server app2:8080 weight=3;
server app3:8080 weight=1;
}
در این حالت سهم Backendها یکسان نیست و Weight در تصمیم Load Balancer دخالت میکند.
HAProxy چیست؟
HAProxy یک Load Balancer و Proxy بسیار شناختهشده برای معماریهای High Availability و Traffic Management است.
HAProxy بهطور ویژه در سناریوهایی که Load Balancing و کنترل دقیق Connectionها اهمیت دارد، بسیار مورد استفاده قرار میگیرد.
قابلیتهای مهم HAProxy شامل موارد زیر است:
- TCP Load Balancing
- HTTP Load Balancing
- Active Health Check
- Passive Health Check
- Session Persistence
- ACL و Content-based Routing
- TLS Termination
- Connection Management
- Queue Management
- Monitoring
- Runtime API
HAProxy همچنین Health Checkهای Active و Passive را ارائه میکند و میتواند Backendهای ناسالم را از Rotation خارج کرده و پس از بازگشت سلامت آنها را دوباره وارد Pool کند.
نمونه ساده HAProxy
frontend http_front
bind *:80
default_backend app_servers
backend app_servers
balance roundrobin
server app1 10.0.0.11:8080 check
server app2 10.0.0.12:8080 check
server app3 10.0.0.13:8080 check
در این مثال:
frontendTraffic ورودی را دریافت میکند.backendمجموعه Serverهای مقصد را تعریف میکند.balance roundrobinالگوریتم توزیع را مشخص میکند.checkباعث فعال شدن Health Check برای Server میشود.
NGINX در برابر HAProxy
| ویژگی | NGINX | HAProxy |
|---|---|---|
| Reverse Proxy | بسیار مناسب | مناسب |
| HTTP Load Balancing | بله | بله |
| TCP Load Balancing | بله | بله |
| UDP Load Balancing | بله | بسته به سناریو و نسخه/تنظیمات |
| Health Check | Passive در Open Source؛ قابلیتهای پیشرفتهتر در Plus | Active و Passive |
| Routing در HTTP | قوی | قوی |
| Static Web Server | بله | هدف اصلی نیست |
| تمرکز اصلی | Web / Proxy / Traffic | Load Balancing / Proxy |
| پیچیدگی Configuration | نسبتاً ساده | بسته به معماری، تخصصیتر |
| Use Case رایج | Web، Reverse Proxy، API، LB | LB، HA، TCP/HTTP Proxy |
این جدول یک مقایسه کلی معماری است؛ قابلیتهای دقیق هر محصول به نسخه و Edition آن بستگی دارد. برای مثال، NGINX Open Source و NGINX Plus از نظر Health Check و برخی قابلیتهای پیشرفته یکسان نیستند.
آیا HAProxy از NGINX سریعتر است؟
پاسخ ساده و عمومی به این سؤال وجود ندارد.
Performance به عوامل زیادی وابسته است:
- نوع Traffic
- Layer مورد استفاده
- تعداد Connectionها
- Keepalive
- TLS
- اندازه Request و Response
- Latency Backend
- الگوریتم Load Balancing
- CPU و Network
- Configuration
- نوع Hardware
در یک معماری واقعی، تفاوت Performance Proxy معمولاً باید با Benchmark متناسب با Workload واقعی سنجیده شود، نه با یک ادعای عمومی مانند «ابزار X همیشه سریعتر است».
HAProxy یا NGINX؛ کدام را انتخاب کنیم؟
انتخاب باید بر اساس نیاز معماری انجام شود.
NGINX میتواند گزینه مناسبی باشد اگر:
- Reverse Proxy نیز مورد نیاز است.
- HTTP/HTTPS بخش اصلی Traffic است.
- Static Content دارید.
- Configuration نسبتاً سادهای میخواهید.
- Routing بر اساس Host و Path مهم است.
- یک Gateway سبک برای چند Application میخواهید.
HAProxy میتواند گزینه مناسبی باشد اگر:
- Load Balancing نقش اصلی Proxy است.
- TCP Load Balancing اهمیت زیادی دارد.
- Health Checkهای دقیق نیاز دارید.
- Connection Management پیچیده است.
- برای Backendهای مختلف سیاستهای متفاوتی میخواهید.
- به قابلیتهای تخصصی Load Balancing نیاز دارید.
این به معنی آن نیست که یکی جای دیگری را در همه معماریها میگیرد؛ هر دو میتوانند برای طیف بزرگی از معماریهای HTTP و TCP استفاده شوند.
Envoy؛ نسل جدیدتر Proxy و Load Balancing
در معماریهای Cloud Native و Microservices، Envoy نیز گزینه مهمی است.
Envoy علاوه بر Load Balancing، قابلیتهایی مانند:
- Dynamic Service Discovery
- Active Health Checking
- Advanced Routing
- Retries
- Circuit Breaking
- Observability
- HTTP/2
- gRPC
- Service Mesh Integration
را ارائه میکند.
Envoy از الگوریتمهایی مانند Weighted Round Robin، Random، Least Request، Ring Hash و Maglev پشتیبانی میکند و میتواند Load Balancing را با Service Discovery و Health Information ترکیب کند.
به همین دلیل Envoy در معماریهایی که Dynamic Service Discovery و Microservices بخش مهمی از سیستم هستند، اهمیت بیشتری پیدا میکند.
Load Balancer در معماری Kubernetes
در Kubernetes، Load Balancing میتواند در چند سطح اتفاق بیفتد.
Internet
│
▼
External Load Balancer
│
▼
Ingress / Gateway
│
▼
Kubernetes Service
│
├── Pod 1
├── Pod 2
├── Pod 3
└── Pod 4
در این معماری، Load Balancer خارجی میتواند Traffic را وارد Cluster کند و Kubernetes Service آن را بین Podها توزیع کند.
در محیطهای پیچیدهتر، Ingress Controller یا Gateway میتواند Layer 7 Routing را انجام دهد.
برای مطالعه بیشتر درباره Kubernetes میتوانید مقاله مقدمهای بر کوبرنتیس و مقاله Kubernetes چیست؟ را مطالعه کنید.
Load Balancer و API Gateway
Load Balancer و API Gateway نیز مفاهیم مشابه اما متفاوتی دارند.
Load Balancer عمدتاً روی توزیع Traffic تمرکز دارد، در حالی که API Gateway معمولاً قابلیتهای Application-level بیشتری مانند:
- Authentication
- Authorization
- Rate Limiting
- Request Transformation
- API Routing
- Versioning
- Policy Enforcement
ارائه میکند.
البته یک Proxy مدرن ممکن است بخشی از هر دو نقش را ایفا کند.
برای آشنایی بیشتر میتوانید مقاله API Gateway چیست؟ را مطالعه کنید.
Load Balancer و High Availability
یک اشتباه بسیار مهم این است که چند Backend داشته باشیم اما خود Load Balancer فقط یک Instance باشد:
Internet
│
▼
Load Balancer
│
┌──────┼──────┐
▼ ▼ ▼
App App App
در این معماری، Load Balancer خودش Single Point of Failure است.
برای حل این مشکل میتوان دو Load Balancer داشت:
Internet
│
Floating / VIP
│
┌───────┴───────┐
▼ ▼
LB-01 LB-02
ACTIVE STANDBY
│ │
└───────┬───────┘
│
Backend Cluster
یکی از ابزارهای رایج برای ایجاد چنین Failoverای Keepalived است. Keepalived از VRRP برای High Availability استفاده میکند و میتواند یک Virtual IP را بین دو Node جابهجا کند.
ترکیب HAProxy و Keepalived
یک معماری رایج در زیرساختهای Self-hosted میتواند این باشد:
Internet
│
Virtual IP
│
┌────────┴────────┐
▼ ▼
HAProxy-01 HAProxy-02
ACTIVE STANDBY
│ │
└────────┬────────┘
│
┌───────┼───────┐
▼ ▼ ▼
App-1 App-2 App-3
در این مدل:
- HAProxy وظیفه Load Balancing را انجام میدهد.
- Keepalived وضعیت High Availability را مدیریت میکند.
- Virtual IP نقطه ورود ثابت برای Clientها ایجاد میکند.
- Backendها به صورت مستقل Health Check میشوند.
این مدل برای بسیاری از Private Cloudها، Data Centerها و زیرساختهای Self-hosted قابل استفاده است.
Load Balancer در Multi-Data Center
وقتی چند Data Center یا Site دارید، مسئله Load Balancing پیچیدهتر میشود.
Global Traffic
│
Global DNS / GSLB
/ \
▼ ▼
Site A Site B
│ │
Local LB Local LB
│ │
Backend Backend
در این معماری، یک لایه Global میتواند Traffic را بین Siteها توزیع کند و Load Balancerهای Local Traffic را داخل هر Site مدیریت کنند.
Envoy نیز در مستندات خود بین Global Load Balancing و Distributed Load Balancing تفکیک قائل میشود و توضیح میدهد که معماریهای پیشرفته میتوانند از هر دو سطح به صورت همزمان استفاده کنند.
در چنین معماریهایی معیارهایی مانند:
- Latency
- Health
- Network Topology
- Capacity
- Data Residency
- Site Availability
میتوانند در تصمیم Routing دخالت داشته باشند.
Load Balancing و Zero Downtime Deployment
Load Balancer یکی از اجزای مهم معماریهای Zero Downtime Deployment است.
برای مثال در Rolling Deployment:
Version 1
Server 1 ──┐
Server 2 ──┼── Traffic
Server 3 ──┘
↓ Deploy
Server 1 → Version 2
Server 2 → Version 1
Server 3 → Version 1
↓
Server 1 → Version 2
Server 2 → Version 2
Server 3 → Version 1
↓
All → Version 2
Load Balancer میتواند Serverهایی را که در حال Deployment هستند موقتاً از Rotation خارج کند و پس از آماده شدن دوباره وارد Pool کند.
برای آشنایی بیشتر با این موضوع، مقاله استراتژیهای Zero Downtime Deployment را مطالعه کنید.
Slow Start چیست؟
فرض کنید یک Backend که مدتی Down بوده دوباره Online شده است.
اگر Load Balancer بلافاصله حجم کامل Traffic را به آن ارسال کند، ممکن است Server تازهراهاندازیشده تحت فشار قرار گیرد.
قابلیتهایی مانند Slow Start برای جلوگیری از این وضعیت در برخی Load Balancerها وجود دارند.
این قابلیت باعث میشود Backend به تدریج Traffic بیشتری دریافت کند تا به ظرفیت عادی برسد.
NGINX Plus و HAProxy قابلیتهایی برای مدیریت ورود مجدد Backendها به Rotation ارائه میکنند، هرچند جزئیات و نام قابلیتها بین محصولات متفاوت است.
Connection Draining چیست؟
در زمان خارج کردن یک Backend از سرویس، ممکن است هنوز Connectionهای فعال داشته باشد.
اگر Connectionها بلافاصله قطع شوند، کاربران ممکن است Error دریافت کنند.
در Connection Draining یا Graceful Shutdown، Backend از دریافت Connectionهای جدید خارج میشود اما Connectionهای فعلی فرصت تکمیل شدن پیدا میکنند.
Backend
│
├── Existing Connections → Complete
│
└── New Connections → Other Backends
این قابلیت در Deployment، Maintenance و Scaling اهمیت زیادی دارد.
Load Balancer و Observability
Load Balancer خودش یکی از منابع مهم Telemetry در یک معماری Production است.
مواردی که بهتر است مانیتور شوند:
- Request Rate
- Response Time
- HTTP Status Codes
- Connection Count
- Backend Health
- Backend Error Rate
- Queue Length
- Traffic Volume
- TLS Errors
- Connection Errors
این اطلاعات کمک میکنند مشخص شود مشکل در Client، Load Balancer، Network یا Backend قرار دارد.
برای مثال:
Client
│
▼
Load Balancer
│
├── Latency normal
├── Backend errors ↑
└── Backend health ↓
│
▼
Problem
Backend
ترکیب Load Balancer با Monitoring و سیستمهای Observability میتواند تشخیص Incident را بسیار سریعتر کند.
Load Balancer و Logging
Access Logهای Load Balancer میتوانند اطلاعات بسیار ارزشمندی ارائه کنند:
- Client IP
- Request Path
- HTTP Method
- Status Code
- Request Time
- Upstream Response Time
- Selected Backend
- User Agent
- Request ID
ارسال این Logها به یک سیستم مرکزی مانند Loki، OpenSearch یا ELK میتواند Debugging را سادهتر کند.
برای آشنایی بیشتر با معماری Log Monitoring میتوانید مقاله مانیتورینگ لاگها با Loki و Grafana را مطالعه کنید.
Load Balancer و Security
Load Balancer میتواند بخشی از Security Architecture نیز باشد.
برای مثال میتوان مواردی مانند:
- TLS Termination
- Access Control
- Rate Limiting
- Header Filtering
- IP Allowlist/Blocklist
- Request Size Limits
- Connection Limits
را در لایه Proxy اعمال کرد.
البته Load Balancer به تنهایی جایگزین WAF یا سیستم کامل DDoS Protection نیست.
در معماریهای جدی، ممکن است Traffic قبل از رسیدن به Load Balancer از CDN، DDoS Protection یا WAF عبور کند.
برای مطالعه بیشتر میتوانید مقاله WAF چیست؟ و مقاله حملات DDoS چیست؟ را بخوانید.
آیا Database را هم باید Load Balance کرد؟
این سؤال پاسخ سادهای ندارد.
برای Applicationهای Stateless، Load Balancing بین چند Web Server معمولاً سادهتر است.
اما Database دارای State و Consistency Requirement است و Load Balancing آن باید با توجه به معماری Database انجام شود.
برای مثال ممکن است معماری به این شکل باشد:
Application
│
▼
Database Proxy
│
┌───┴────┐
▼ ▼
Primary Replica
│
▼
Read
در چنین معماریهایی ابزارهایی مانند HAProxy یا ProxySQL میتوانند در لایه Database نیز نقش داشته باشند، اما تصمیم درباره Routing Read/Write باید بر اساس معماری واقعی Database انجام شود.
برای مطالعه بیشتر درباره ProxySQL میتوانید مقاله ProxySQL چیست؟ را مطالعه کنید.
Load Balancing برای Cache
Cache نیز میتواند به Load Balancing نیاز داشته باشد.
اما برخلاف HTTP Server، انتخاب الگوریتم اهمیت بسیار بیشتری پیدا میکند؛ زیرا اگر Cache Keyها به صورت نامناسب بین Nodeها توزیع شوند، Cache Hit Rate کاهش پیدا میکند.
در این سناریو Consistent Hashing میتواند گزینه مناسبی باشد.
این موضوع یکی از دلایلی است که نباید همه Load Balancingها را با Round Robin حل کرد.
مقایسه NGINX، HAProxy و Envoy
| ویژگی | NGINX | HAProxy | Envoy |
|---|---|---|---|
| HTTP Proxy | بسیار مناسب | مناسب | بسیار مناسب |
| TCP Proxy | بله | بله | بله |
| UDP | بله | بسته به سناریو | قابلیتهای مرتبط بسته به معماری |
| Health Check | خوب | بسیار قوی | بسیار قوی |
| Dynamic Service Discovery | محدودتر | محدودتر | بسیار قوی |
| Microservices | مناسب | مناسب | بسیار مناسب |
| Service Mesh | معمولاً انتخاب اصلی نیست | معمولاً انتخاب اصلی نیست | یکی از کاربردهای مهم |
| Reverse Proxy | بسیار قوی | قوی | قوی |
| سادگی برای Web | بالا | متوسط | پایینتر |
| تمرکز | Web / Proxy / LB | LB / Proxy / HA | Cloud Native Proxy |
این مقایسه به معنی برتری مطلق یک ابزار نیست. Envoy برای معماریهای Dynamic و Cloud Native امکانات متفاوتی نسبت به NGINX یا HAProxy ارائه میکند و انتخاب نهایی باید بر اساس نیاز واقعی سیستم انجام شود.
چگونه یک Load Balancer مناسب انتخاب کنیم؟
به جای شروع با سؤال «NGINX بهتر است یا HAProxy؟» بهتر است ابتدا نیاز معماری را مشخص کنیم.
سؤال اول: Traffic شما چیست؟
- HTTP/HTTPS
- TCP
- UDP
- gRPC
- Database Traffic
- Mixed Traffic
سؤال دوم: به Layer 7 نیاز دارید؟
اگر Routing بر اساس Host، Path، Header یا Cookie لازم باشد، Layer 7 اهمیت پیدا میکند.
سؤال سوم: Health Check چقدر مهم است؟
برای سیستمهای حیاتی، Active Health Check، Failure Threshold، Recovery Threshold و Graceful Re-entry اهمیت زیادی دارند.
سؤال چهارم: Load Balancer خودش چگونه HA میشود؟
اگر یک Load Balancer تنها نقطه ورود سیستم باشد، باید برای Failover آن نیز برنامه داشته باشید.
سؤال پنجم: Traffic چقدر Dynamic است؟
اگر Backendها دائماً اضافه و حذف میشوند، Service Discovery و Dynamic Configuration اهمیت بیشتری پیدا میکنند.
سؤال ششم: Observability چگونه انجام میشود؟
باید بدانید در صورت افزایش Latency یا Error Rate، مشکل دقیقاً در کدام لایه قرار دارد.
یک معماری Production پیشنهادی
برای یک Application متوسط تا بزرگ میتوان معماری زیر را در نظر گرفت:
Internet
│
▼
CDN / DDoS / WAF
│
▼
Floating IP / VIP
│
┌──────────┴──────────┐
▼ ▼
Load Balancer 1 Load Balancer 2
ACTIVE STANDBY
│ │
└──────────┬──────────┘
│
Application Pool
┌─────────┼─────────┐
▼ ▼ ▼
App-1 App-2 App-3
│ │ │
└─────────┼─────────┘
│
┌──────────┴──────────┐
▼ ▼
Database Cache
│
▼
Backup / DR
در چنین معماریای هر لایه وظیفه مشخصی دارد:
- CDN/DDoS/WAF برای لایه Edge و Security
- Load Balancer برای Traffic Distribution
- Keepalived یا مکانیزم مشابه برای HA لایه Load Balancer
- Application Cluster برای Horizontal Scaling
- Database Layer برای Data Persistence
- Cache برای کاهش فشار روی Backend
- Backup و DR برای Recovery
اشتباهات رایج در طراحی Load Balancer
۱. فقط یک Load Balancer داشتن
در این حالت Load Balancer خودش Single Point of Failure است.
۲. نداشتن Health Check
ممکن است Traffic همچنان به Backend خراب ارسال شود.
۳. استفاده از Round Robin برای همه چیز
الگوریتم مناسب به نوع Workload بستگی دارد.
۴. استفاده بیدلیل از Sticky Session
Sticky Session میتواند معماری Stateless را پیچیده کند و Scaling را دشوارتر کند.
۵. نداشتن Connection Draining
Deployment یا Maintenance میتواند باعث قطع Connectionهای فعال شود.
۶. نداشتن Monitoring
بدون Metrics و Logs، تشخیص اینکه مشکل در Load Balancer یا Backend است دشوار خواهد بود.
۷. نادیده گرفتن Load Balancer در Disaster Recovery
اگر فقط Backendها را Redundant کنید اما مسیر ورود Traffic را Redundant نکنید، هنوز یک نقطه شکست مهم دارید.
۸. قرار دادن همه Routing Logic در یک Configuration پیچیده
هرچه Routing پیچیدهتر شود، مدیریت Configuration و Change Management نیز اهمیت بیشتری پیدا میکند.
Load Balancer و خدمات دواپس
طراحی Load Balancer معمولاً بخشی از یک پروژه بزرگتر زیرساخت است و در کنار خدمات دواپس و خدمات DevOps باید به صورت یکپارچه با CI/CD، Monitoring، Security و Scaling طراحی شود.
برای مثال، وقتی یک Application به صورت خودکار Deploy میشود، Load Balancer باید بتواند Backendهای جدید را وارد Pool کند، Backendهای در حال Upgrade را از Rotation خارج کند و پس از موفقیت Health Check دوباره آنها را فعال کند.
این ارتباط میان Deployment و Load Balancing یکی از پایههای معماریهای Zero Downtime است.
چکلیست یک Load Balancer Production
- ☐ Layer مناسب برای Traffic مشخص شده است.
- ☐ الگوریتم Load Balancing بر اساس Workload انتخاب شده است.
- ☐ Health Check فعال است.
- ☐ Failure و Recovery Threshold مشخص شده است.
- ☐ Connection Timeoutها تنظیم شدهاند.
- ☐ Keepalive بر اساس نیاز Application تنظیم شده است.
- ☐ TLS Certificateها مدیریت میشوند.
- ☐ Logging فعال است.
- ☐ Metrics جمعآوری میشوند.
- ☐ Backendها Gracefully از Rotation خارج میشوند.
- ☐ Load Balancer خودش High Availability دارد.
- ☐ Failover تست شده است.
- ☐ ظرفیت Load Balancer تحت Load Test بررسی شده است.
- ☐ Configuration قابل Version Control است.
- ☐ تغییرات Configuration فرآیند Review و Rollback دارند.
- ☐ سناریوی Disaster Recovery برای لایه Load Balancing مشخص است.
جمعبندی
Load Balancer یکی از اجزای پایهای معماریهای Scalable و Highly Available است، اما انتخاب و طراحی آن نباید صرفاً بر اساس نام ابزار انجام شود.
NGINX یک انتخاب قدرتمند برای Reverse Proxy، Web Traffic، HTTP/HTTPS و بسیاری از سناریوهای Load Balancing است. HAProxy نیز در Load Balancing تخصصی، TCP/HTTP Proxying، Health Check و مدیریت دقیق Traffic جایگاه مهمی دارد. Envoy نیز برای معماریهای Cloud Native، Dynamic Service Discovery و Microservices قابلیتهای پیشرفتهای ارائه میکند.
مهمتر از انتخاب ابزار، طراحی صحیح معماری است. یک Load Balancer حرفهای باید در کنار Health Check، High Availability، Observability، Security، Connection Management و Deployment Strategy دیده شود.
در نهایت، سؤال درست این نیست که «NGINX بهتر است یا HAProxy؟»؛ سؤال درست این است که چه نوع Traffic، چه سطحی از Availability، چه مدل Scaling و چه نیاز Routingی داریم و کدام معماری میتواند این نیازها را با پیچیدگی قابل قبول برآورده کند؟
سؤالات متداول
Load Balancer چیست؟
Load Balancer سیستمی است که Traffic ورودی را بین چند Backend توزیع میکند و میتواند قابلیتهایی مانند Health Check، Routing، TLS Termination و Failover را نیز ارائه دهد.
تفاوت Layer 4 و Layer 7 چیست؟
Layer 4 عمدتاً بر TCP/UDP و Connection تمرکز دارد، در حالی که Layer 7 اطلاعات Application مانند HTTP Host، Path و Header را نیز میتواند در تصمیم Routing در نظر بگیرد.
آیا NGINX یک Load Balancer است؟
بله. NGINX میتواند به عنوان HTTP/HTTPS Load Balancer و همچنین TCP/UDP Load Balancer مورد استفاده قرار گیرد.
آیا HAProxy فقط برای Load Balancing است؟
خیر. HAProxy علاوه بر Load Balancing، قابلیتهای Proxy، Health Check، Connection Management، Routing و Traffic Control را نیز ارائه میکند.
NGINX بهتر است یا HAProxy؟
هیچ پاسخ عمومی برای همه معماریها وجود ندارد. انتخاب به نوع Traffic، Layer، نیازهای Health Check، Routing، HA، پیچیدگی Configuration و سایر نیازهای زیرساخت بستگی دارد.
آیا Load Balancer باعث High Availability میشود؟
Load Balancer میتواند Availability Application را افزایش دهد، اما اگر خود Load Balancer فقط یک Instance داشته باشد، همچنان میتواند Single Point of Failure باشد. برای معماری کاملتر باید خود لایه Load Balancing نیز Redundant شود.
آیا برای Kubernetes به Load Balancer نیاز داریم؟
بسته به معماری، بله. Kubernetes میتواند Traffic را در داخل Cluster توزیع کند، اما برای ورود Traffic از بیرون Cluster معمولاً به یک Load Balancer، Ingress، Gateway یا ترکیبی از این اجزا نیاز است.
طراحی Load Balancing برای زیرساختهای سازمانی
آلتیمیت کلاد میتواند معماری Load Balancing را متناسب با نیاز سازمان طراحی و پیادهسازی کند؛ از یک Reverse Proxy ساده تا معماریهای High Availability، Multi-Node، Multi-Data Center و Kubernetes.
این طراحی میتواند در کنار High Availability، Scaling، Monitoring، Containerization و Disaster Recovery انجام شود تا Load Balancer صرفاً یک Proxy جلوی Application نباشد و به بخشی از معماری تابآور زیرساخت تبدیل شود.
برای بررسی معماری Load Balancing و High Availability زیرساخت خود با آلتیمیت کلاد در ارتباط باشید.