راهاندازی HAProxy برای Load Balancer بین چند سرور مجازی و اختصاصی
وقتی یک وبسایت فقط روی یک سرور اجرا میشود، تمام درخواستها، پردازشها و وابستگیهای سرویس به همان ماشین متکی هستند. افزایش ترافیک میتواند منابع آن را پر کند و خرابی سرور نیز کل سرویس را از دسترس خارج میکند. یکی از راههای کاهش این وابستگی، اجرای برنامه روی چند سرور و قرار دادن یک Load Balancer در جلوی آنهاست؛ همین الگو در مقیاس بزرگتر، مثلاً برای Load Balancer در کلاستر Kubernetes، هم کاربرد دارد.
HAProxy یک پراکسی معکوس و توزیعکننده بار متنباز است که میتواند درخواستهای TCP و HTTP را میان چند سرور مجازی یا اختصاصی تقسیم کند. این نرمافزار علاوه بر توزیع ترافیک، وضعیت سرورهای پشت صحنه را بررسی میکند و سرورهای معیوب را موقتاً از چرخه خارج میکند.
در این آموزش، راهاندازی HAProxy برای Load Balancer را با یک سناریوی عملی بررسی میکنیم: یک سرور HAProxy در ورودی و سه وبسرور Nginx در لایه Backend.

معماری نمونه و پیشنیازها
فرض میکنیم چهار سرور با سیستمعامل Ubuntu 24.04 یا 22.04 در اختیار داریم:
- سرور Load Balancer با IP عمومی 203.0.113.10
- وبسرور اول با IP خصوصی 10.10.0.11
- وبسرور دوم با IP خصوصی 10.10.0.12
- وبسرور سوم با IP خصوصی 10.10.0.13
آدرسهای بالا نمونه هستند و باید آنها را با IP واقعی سرورها جایگزین کنید. بهتر است ارتباط HAProxy با Backendها از طریق شبکه خصوصی انجام شود. به این ترتیب، ترافیک داخلی از اینترنت عمومی عبور نمیکند و لازم نیست پورت وبسرورها برای همه IPها باز باشد.
برای اجرای این سناریو به دسترسی sudo، ارتباط شبکه میان سرورها و پورتهای باز موردنیاز احتیاج دارید. روی سرور HAProxy معمولاً پورتهای 80 و 443 از اینترنت پذیرفته میشوند. روی Backendها نیز پورت سرویس، در این مثال 80، فقط باید از IP سرور HAProxy قابل دسترسی باشد؛ برای اعمال این محدودیت میتوان از فایروال UFW روی هر Backend استفاده کرد.
یک Load Balancer بهتنهایی نقطه خرابی ورودی را حذف نمیکند. اگر دسترسپذیری در سطح ورودی حیاتی است، باید در مرحله بعد دو نمونه HAProxy همراه با یک IP مجازی یا سرویس Failover راهاندازی کنید. این مقاله روی توزیع بار میان Backendها تمرکز دارد.
آمادهسازی وبسرورهای Nginx
ابتدا روی هر سه سرور Backend، Nginx را نصب کنید:
sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
برای اینکه هنگام آزمایش مشخص شود پاسخ از کدام سرور آمده، صفحه اصلی هر Backend را متفاوت میسازیم. روی سرور اول اجرا کنید:
echo '<h1>Backend 1</h1>' | sudo tee /var/www/html/index.html
روی سرور دوم:
echo '<h1>Backend 2</h1>' | sudo tee /var/www/html/index.html
و روی سرور سوم:
echo '<h1>Backend 3</h1>' | sudo tee /var/www/html/index.html
سپس از سرور Load Balancer بررسی کنید که هر سه مقصد قابل دسترسی باشند:
curl http://10.10.0.11
curl http://10.10.0.12
curl http://10.10.0.13
اگر یکی از درخواستها پاسخ نمیدهد، پیش از نصب HAProxy مسیر شبکه، فایروال سیستمعامل، Security Group و وضعیت Nginx را بررسی کنید. HAProxy نمیتواند مشکل ارتباط پایه میان سرورها را برطرف کند.
نصب HAProxy روی سرور Load Balancer
روی سرور ورودی، بسته HAProxy را از مخزن سیستمعامل نصب کنید:
sudo apt update
sudo apt install -y haproxy
نسخه نصبشده را ببینید:
haproxy -v
سرویس را نیز برای اجرا پس از راهاندازی مجدد سیستم فعال کنید:
sudo systemctl enable haproxy
فایل اصلی پیکربندی در اوبونتو و دبیان معمولاً در مسیر زیر قرار دارد:
/etc/haproxy/haproxy.cfg
پیش از تغییر فایل، یک نسخه پشتیبان بسازید:
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
ساخت پیکربندی اولیه HAProxy
پیکربندی HAProxy معمولاً از چهار بخش تشکیل میشود: global برای تنظیمات سطح پردازش، defaults برای مقادیر پیشفرض، frontend برای ورودی درخواستها و backend برای تعریف سرورهای مقصد.
فایل /etc/haproxy/haproxy.cfg را با ویرایشگر دلخواه باز کنید و نمونه زیر را متناسب با شبکه خود قرار دهید:
global
log /dev/log local0
log /dev/log local1 notice
user haproxy
group haproxy
daemon
maxconn 4096
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
frontend http_front
bind *:80
default_backend web_servers
backend web_servers
balance roundrobin
option httpchk GET /
http-check expect status 200
server web1 10.10.0.11:80 check
server web2 10.10.0.12:80 check
server web3 10.10.0.13:80 check
در بخش frontend، دستور bind *:80 باعث میشود HAProxy روی پورت ۸۰ تمام رابطهای شبکه گوش دهد. default_backend نیز درخواستها را به مجموعه web_servers میفرستد.
در بخش Backend، الگوریتم roundrobin درخواستها را بهترتیب میان سرورها پخش میکند. گزینه check در انتهای هر خط، بررسی سلامت آن سرور را فعال میکند. دستورهای option httpchk و http-check expect مشخص میکنند که HAProxy مسیر / را درخواست کند و کد وضعیت 200 را پاسخ سالم بداند.
بررسی پیکربندی پیش از اجرا
یک اشتباه تایپی میتواند از شروع سرویس جلوگیری کند. قبل از Reload یا Restart، فایل را اعتبارسنجی کنید:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
اگر پیام معتبر بودن پیکربندی نمایش داده شد، سرویس را راهاندازی مجدد کنید:
sudo systemctl restart haproxy
sudo systemctl status haproxy
برای تغییرات بعدی میتوانید پس از اعتبارسنجی از Reload استفاده کنید تا اتصالهای موجود با اختلال کمتری روبهرو شوند:
sudo systemctl reload haproxy
انتخاب الگوریتم مناسب توزیع بار
HAProxy چند الگوریتم برای انتخاب Backend دارد. انتخاب درست به نوع برنامه، طول اتصالها و تفاوت ظرفیت سرورها بستگی دارد.
| الگوریتم | رفتار | کاربرد مناسب |
|---|---|---|
roundrobin | درخواستها را بهترتیب پخش میکند | وبسرورهای همظرفیت و درخواستهای مشابه |
leastconn | سروری را انتخاب میکند که اتصال فعال کمتری دارد | اتصالهای طولانی یا زمان پردازش نامتوازن |
source | مقصد را بر اساس IP مبدأ انتخاب میکند | حفظ نسبی وابستگی کاربر به یک Backend |
random | مقصد را با انتخاب تصادفی کنترلشده تعیین میکند | کلاسترهای بزرگ و بار عمومی |
اگر یک سرور اختصاصی قوی در کنار دو VPS کوچک دارید، تقسیم برابر ترافیک منطقی نیست. برای تعیین سهم هر سرور میتوان از weight استفاده کرد:
backend web_servers
balance roundrobin
server dedicated1 10.10.0.11:80 check weight 4
server vps1 10.10.0.12:80 check weight 2
server vps2 10.10.0.13:80 check weight 2
در این نمونه، سرور اختصاصی تقریباً دو برابر هر VPS سهم میگیرد. وزن مناسب را باید با توجه به CPU، حافظه، توان شبکه و نتایج آزمون بار تعیین کنید؛ تعداد هسته بهتنهایی معیار کافی نیست.
تنظیم Health Check دقیقتر
بررسی صفحه اصلی همیشه روش خوبی برای سنجش سلامت برنامه نیست. ممکن است Nginx پاسخ 200 بدهد، اما برنامه به دیتابیس دسترسی نداشته باشد. بهتر است برنامه یک مسیر سبک مانند /health داشته باشد که وابستگیهای ضروری را بررسی کند.
پیکربندی Backend در این حالت میتواند چنین باشد:
backend web_servers
balance leastconn
option httpchk GET /health
http-check expect status 200
default-server inter 3s fall 3 rise 2
server web1 10.10.0.11:80 check
server web2 10.10.0.12:80 check
server web3 10.10.0.13:80 check
پارامتر inter 3s فاصله بررسیها را سه ثانیه تعیین میکند. fall 3 یعنی پس از سه بررسی ناموفق، سرور Down شناخته شود. rise 2 نیز بازگشت سرور را به دو بررسی موفق متوالی وابسته میکند. این آستانهها از خارج و وارد شدن مکرر یک Backend ناپایدار جلوگیری میکنند.
مسیر Health Check نباید عملیات سنگین اجرا کند. همچنین بهتر است فقط وابستگیهایی را بررسی کند که نبود آنها واقعاً مانع پاسخگویی برنامه میشود. وابسته کردن این مسیر به یک سرویس جانبی غیرضروری ممکن است تمام Backendها را همزمان ناسالم نشان دهد.
عبور دادن اطلاعات واقعی کاربر
چون اتصال HTTP ابتدا به HAProxy میرسد، وبسرور ممکن است IP پراکسی را بهجای IP کاربر ثبت کند. با افزودن option forwardfor، HAProxy آدرس کاربر را در هدر X-Forwarded-For قرار میدهد:
backend web_servers
balance roundrobin
option forwardfor
option httpchk GET /health
server web1 10.10.0.11:80 check
server web2 10.10.0.12:80 check
server web3 10.10.0.13:80 check
برای تشخیص پروتکل اصلی نیز میتوانید در Frontend هدر زیر را تنظیم کنید:
frontend http_front
bind *:80
http-request set-header X-Forwarded-Proto http
default_backend web_servers
در محیط HTTPS مقدار این هدر باید متناسب با محل پایان TLS تنظیم شود. برنامه یا Nginx نیز باید فقط هدرهای پراکسیهای مورد اعتماد را بپذیرد؛ اعتماد عمومی به X-Forwarded-For امکان جعل IP را ایجاد میکند. فهرست کاملتری از این نکات در ترفندهای امنیتی Nginx آمده است.
فعالسازی صفحه آمار
HAProxy یک صفحه داخلی برای مشاهده وضعیت Backendها، تعداد اتصالها و نتیجه Health Check دارد. آن را روی یک پورت جداگانه فعال کنید:
listen stats
bind 127.0.0.1:8404
mode http
stats enable
stats uri /stats
stats refresh 10s
اتصال به 127.0.0.1 باعث میشود صفحه مستقیماً از اینترنت قابل دسترسی نباشد. برای مشاهده آن میتوانید تونل SSH بسازید:
ssh -L 8404:127.0.0.1:8404 user@203.0.113.10
سپس در مرورگر آدرس http://127.0.0.1:8404/stats را باز کنید. اگر لازم است این صفحه از شبکه مدیریتی دیده شود، دسترسی را با فایروال، احراز هویت و محدودیت IP کنترل کنید.
آزمایش توزیع بار و خرابی Backend
پس از اجرای سرویس، چند درخواست متوالی به IP عمومی Load Balancer بفرستید:
for i in $(seq 1 9); do
curl -s http://203.0.113.10
done
با الگوریتم roundrobin باید پاسخ Backendهای مختلف را ببینید. سپس Nginx را موقتاً روی یکی از Backendها متوقف کنید:
sudo systemctl stop nginx
پس از گذشت بازه Health Check، درخواستها باید فقط به دو سرور سالم برسند. برای بازگرداندن سرور اجرا کنید:
sudo systemctl start nginx
این آزمایش نشان میدهد حذف و بازگشت Backend درست کار میکند، اما جای آزمون بار را نمیگیرد. پیش از انتقال ترافیک واقعی، ظرفیت HAProxy و وبسرورها را با الگویی نزدیک به رفتار کاربران آزمایش کنید.

نکات مهم برای محیط عملیاتی
Timeoutها را متناسب با برنامه تنظیم کنید. مقدار بسیار کم ممکن است درخواستهای معتبر را قطع کند و مقدار بسیار زیاد، اتصالهای معیوب را مدت بیشتری نگه دارد. برای WebSocket، دانلود فایلهای بزرگ یا APIهای پردازشمحور باید زمانهای client و server جداگانه بررسی شوند.
اگر برنامه Session را در حافظه محلی هر Backend نگه میدارد، جابهجایی کاربر میان سرورها مشکل ایجاد میکند. راه پایدارتر، انتقال Session به یک مخزن مشترک مانند Redis است. قابلیت Sticky Session در HAProxy نیز وجود دارد، اما وابستگی به یک Backend را بیشتر میکند و باید آگاهانه انتخاب شود.
TLS را میتوان روی HAProxy خاتمه داد و ترافیک را داخل شبکه خصوصی بهصورت HTTP فرستاد. در شبکههای نامطمئن یا محیطهایی با الزام امنیتی، ارتباط HAProxy تا Backend نیز باید رمزنگاری شود. تمدید خودکار گواهی، محدود کردن نسخههای TLS و نگهداری امن کلید خصوصی بخشی از آمادهسازی HTTPS هستند.
لاگهای HAProxy را به سامانه مانیتورینگ بفرستید و شاخصهایی مانند نرخ خطای 5xx، زمان پاسخ، تعداد اتصالهای فعال و تعداد Backendهای سالم را زیر نظر بگیرید. صرف روشن بودن سرویس به معنای عملکرد درست آن نیست؛ ابزارها و راهکارهای مانیتورینگ لینوکس نقطه شروع خوبی برای این کار هستند.
انتخاب زیرساخت برای HAProxy و Backendها
میتوانید خود HAProxy را روی یک VPS سبک اجرا کنید و Backendهای قویتر را روی VPS یا سرور اختصاصی قرار دهید. انتخاب منابع به نرخ درخواست، تعداد اتصال همزمان، حجم TLS و پهنای باند بستگی دارد. برای شروع، اندازهگیری مصرف واقعی بهتر از انتخاب منابع بر اساس حدس است. اگر برای ساخت این معماری به سرورهای مستقل نیاز دارید، مشخصات و پلنهای سرور مجازی ابری آریاسرویس را میتوانید بررسی کنید. هر Backend باید IP خصوصی پایدار، منابع قابل پیشبینی و امکان اعمال قواعد فایروال داشته باشد.
جمعبندی
راهاندازی HAProxy برای Load Balancer با تعریف یک Frontend، یک Backend و فعال کردن Health Check شروع میشود. در نمونه این مقاله، درخواستهای ورودی میان سه وبسرور Nginx توزیع شدند و Backend معیوب بهصورت خودکار از چرخه کنار رفت. برای استفاده عملی، الگوریتم توزیع بار و وزن سرورها را بر اساس ظرفیت واقعی انتخاب کنید، مسیر Health Check اختصاصی بسازید، دسترسی شبکه Backendها را محدود نگه دارید و رفتار سیستم را با لاگ و متریک بررسی کنید. اگر قطع شدن سرور HAProxy نیز قابل قبول نیست، دو Load Balancer و سازوکار Failover مرحله بعدی معماری خواهند بود.




