کانفیگ nginx به‌عنوان Load Balancer (پخش بار روی چند سرور)

وقتی یک سرور برنامه کافی نیست، nginx می‌تواند درخواست‌ها را بین چند سرور پخش کند و در صورت خرابی یکی از آن‌ها ترافیک را به بقیه بدهد. این ساختار مقیاس‌پذیری و دسترس‌پذیری بالاتری فراهم می‌کند.

وب‌سرور و SSLپیشرفته12 دقیقه

۱تعریف upstream با چند سرور

پیش‌فرض nginx الگوریتم round-robin است. با weight می‌توانید به سرور قوی‌تر درخواست بیشتری بدهید. max_fails و fail_timeout به‌صورت غیرفعال (passive) سلامت سرور را می‌سنجند.

nginx
upstream app_cluster {
    server 10.0.0.11:3000 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.0.12:3000 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.13:3000 backup;      # فقط وقتی بقیه از کار افتاده‌اند
    keepalive 32;
}

۲انتخاب الگوریتم پخش بار

یکی از روش‌های زیر را در ابتدای بلوک upstream اضافه کنید.

nginx
upstream app_cluster {
    least_conn;          # سرور با کمترین اتصال فعال
    # ip_hash;           # هر کاربر همیشه به یک سرور (session چسبنده)
    # hash $request_uri consistent;   # توزیع بر اساس آدرس (مناسب کش)
    server 10.0.0.11:3000;
    server 10.0.0.12:3000;
}

اگر برنامه session را در حافظهٔ محلی نگه می‌دارد ip_hash لازم است؛ بهتر است session را در Redis نگه دارید تا هر سرور بتواند هر درخواستی را پاسخ دهد.

۳server block با proxy_pass

همان الگوی reverse proxy ولی با نام upstream. proxy_next_upstream تعیین می‌کند در چه خطاهایی درخواست به سرور بعدی برود.

nginx
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://app_cluster;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";

        proxy_next_upstream error timeout http_502 http_503 http_504;
        proxy_next_upstream_tries 2;
        proxy_connect_timeout 3s;
    }
}

درخواست‌های غیرایمن (POST) را به‌صورت پیش‌فرض nginx به سرور بعدی نمی‌فرستد تا عملیات دوبار انجام نشود.

۴مشاهدهٔ اینکه کدام سرور پاسخ داده

با یک هدر و log_format می‌توانید سرور مقصد را در لاگ و پاسخ ببینید و تعادل بار را بررسی کنید.

nginx
log_format upstream_log '$remote_addr - $request [$status] $upstream_addr $upstream_response_time';
access_log /var/log/nginx/app.access.log upstream_log;

# در server block
add_header X-Upstream $upstream_addr always;

۵تست پخش بار

چند درخواست پشت‌سرهم بفرستید و توزیع را در لاگ بررسی کنید.

bash
for i in $(seq 1 12); do curl -s -o /dev/null -D - https://app.example.com | grep -i x-upstream; done
awk '{print $5}' /var/log/nginx/app.access.log | sort | uniq -c

۶خارج کردن یک سرور برای نگه‌داری

با علامت down سرور از چرخه خارج می‌شود بدون اینکه بقیه تنظیمات تغییر کند. سپس reload کنید.

nginx
upstream app_cluster {
    server 10.0.0.11:3000;
    server 10.0.0.12:3000 down;   # موقتاً خارج از سرویس
}

پرسش‌های پرتکرار دربارهٔ کانفیگ nginx به‌عنوان Load Balancer (پخش بار روی چند سرور)

آیا nginx رایگان health check فعال دارد؟

نسخهٔ متن‌باز فقط health check غیرفعال (با max_fails و fail_timeout) دارد. health check فعال در NGINX Plus است؛ اما می‌توانید از HAProxy یا ماژول‌های شخص ثالث استفاده کنید.

آیا خود load balancer نقطهٔ شکست واحد نیست؟

چرا. برای دسترس‌پذیری کامل دو load balancer را با IP شناور (keepalived و VRRP) یا DNS چندگانه اجرا کنید.