İçeriğe geç

(B) DevOps

Nginx Load Balancing: Adim Adim Rehber

10 dk okuma

Web uygulamalarında kullanıcı ve trafik sayısının artmasıyla birlikte gelen isteklerin birden fazla sunucuya dağıtılması, sistem performansı, ölçeklenebilirlik ve yüksek kullanılabilirlik açısından kritik hale gelir. Nginx Load Balancing, gelen istemci isteklerini birden fazla backend sunucusuna dağıtarak bu ihtiyaca etkili bir çözüm sunar.

Bu rehberde Nginx load balancing yapılandırmasını, desteklenen yük dengeleme algoritmalarını, failover ayarlarını, SSL/TLS terminasyonunu ve gerçek kullanım senaryolarına uygun yapılandırma örneklerini adım adım inceleyeceğiz.

Load Balancing Nedir?

Load balancing, istemcilerden gelen ağ isteklerinin birden fazla sunucu arasında dağıtılması işlemidir. Bu yapı sayesinde tek bir sunucunun aşırı yüklenmesi önlenebilir ve sistem kaynakları daha verimli kullanılabilir.

Yatay ölçeklendirme olarak da bilinen bu yaklaşım, uygulamaya yeni sunucular eklenerek kapasitenin artırılmasına olanak tanır. Ayrıca backend sunuculardan birinin erişilemez hale gelmesi durumunda Nginx, başarısız sunucuyu geçici olarak devre dışı bırakıp istekleri diğer sunuculara yönlendirebilir.

Nginx, reverse proxy özelliklerinin yanı sıra HTTP, HTTPS ve TCP tabanlı servisler için load balancing özellikleri sunar. HTTP load balancing yapılandırmasında farklı dağıtım algoritmaları kullanılabilir ve pasif health check mekanizması sayesinde başarısız backend sunucular geçici olarak devre dışı bırakılabilir.

Nginx Load Balancing Yapılandırması

Nginx ile HTTP load balancing yapılandırmak için öncelikle bir upstream grubu oluşturulur. upstream bloğu, Nginx'in istekleri yönlendireceği backend sunucu havuzunu tanımlar.

upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

Bu yapılandırmada üç farklı backend sunucusu tanımlanmıştır. Ek bir algoritma belirtilmediği için Nginx varsayılan olarak Round Robin yöntemini kullanır.

Daha sonra server bloğunda proxy_pass direktifi kullanılarak gelen HTTP istekleri oluşturduğumuz backend grubuna yönlendirilir:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        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;
    }
}

X-Forwarded-For, istemcinin IP adresinin proxy zinciri boyunca aktarılmasına yardımcı olur. X-Forwarded-Proto ise istemcinin HTTP veya HTTPS üzerinden bağlandığı bilgisinin backend uygulamasına iletilmesini sağlar.

Nginx Load Balancing Algoritmaları

Nginx, backend sunucular arasında trafik dağıtmak için birden fazla load balancing yöntemi sunar. Kullanılacak algoritma; uygulamanın trafik yapısına, isteklerin süresine ve backend sunucularının donanım kapasitelerine göre belirlenmelidir.

Round Robin

Round Robin, Nginx'te varsayılan load balancing yöntemidir. İstekler backend sunucular arasında sıralı şekilde dağıtılır.

Backend sunucuların benzer kapasiteye sahip olduğu ve isteklerin işlem sürelerinin birbirine yakın olduğu senaryolarda basit ve etkili bir seçimdir.

upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

Least Connections

Least Connections algoritması, aktif bağlantı sayısı en düşük olan backend sunucusuna yeni isteği yönlendirmeyi tercih eder. Özellikle isteklerin işlem sürelerinin farklı olduğu veya uzun süre açık bağlantıların bulunduğu uygulamalarda faydalı olabilir.

upstream backend {
    least_conn;

    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

Bu yöntem, yalnızca sunucuların işlemci veya RAM kullanımını doğrudan ölçmez. Dağıtım kararında aktif bağlantı sayısını temel alır.

IP Hash

IP Hash, istemcinin IP adresini temel alarak aynı istemcinin isteklerini mümkün olduğunca aynı backend sunucusuna yönlendirmeyi sağlar. Bu yöntem, uygulamanın oturum bilgisini sunucu üzerinde tuttuğu bazı senaryolarda kullanılabilir.

upstream backend {
    ip_hash;

    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

Ancak IP Hash gerçek anlamda bir oturum yönetim sistemi değildir. NAT kullanan çok sayıda kullanıcının aynı public IP üzerinden geldiği ortamlarda yük dağılımı dengesizleşebilir. Modern uygulamalarda mümkünse merkezi session storage veya stateless authentication gibi yöntemler tercih edilebilir.

Weighted Load Balancing

Weighted Load Balancing, farklı donanım kapasitesine sahip backend sunucuların bulunduğu ortamlarda kullanılabilir. weight değeri yüksek olan sunucu, diğer sunuculara göre daha fazla trafik alır.

upstream backend {
    server 10.0.0.1:8080 weight=3;
    server 10.0.0.2:8080 weight=2;
    server 10.0.0.3:8080 weight=1;
}

Bu örnekte teorik olarak trafik dağılımında ilk sunucuya 3, ikinci sunucuya 2, üçüncü sunucuya ise 1 oranında ağırlık verilmiştir.

Weight değeri least_conn ile de birlikte kullanılabilir:

upstream backend {
    least_conn;

    server 10.0.0.1:8080 weight=3;
    server 10.0.0.2:8080 weight=2;
    server 10.0.0.3:8080 weight=1;
}

Backend Failover ve Pasif Health Check

Nginx'in açık kaynak sürümünde backend sağlık kontrolü temel olarak pasif health check mantığıyla çalışır. Nginx, gerçek trafik sırasında backend sunuculara yapılan isteklerin sonuçlarını takip eder. Belirlenen sayıda başarısız denemeden sonra backend sunucuyu belirli bir süre için geçici olarak devre dışı bırakabilir.

upstream backend {
    server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080 max_fails=3 fail_timeout=30s;
}

Bu yapılandırmada max_fails=3, Nginx'in ilgili backend'i başarısız olarak değerlendirmeden önce belirli koşullarda üç başarısız denemeye kadar tolerans göstermesini sağlar. fail_timeout=30s ise başarısızlık sayacının değerlendirilmesinde kullanılan ve backend'in geçici olarak kullanılamaz kabul edildiği süreyle ilişkili zaman aralığını belirtir.

Bu mekanizma, harici bir health check servisi gibi periyodik olarak ayrı bir HTTP endpoint'i kontrol eden aktif health check sistemiyle aynı şey değildir. Gelişmiş aktif health check özellikleri için Nginx'in kullanılan sürümüne ve dağıtımına göre ek çözümler veya ticari özellikler gerekebilir.

Backup Sunucu

Kritik sistemlerde bir backend sunucuyu yalnızca diğer sunucular kullanılamadığında devreye girecek şekilde backup olarak tanımlayabilirsiniz:

upstream backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080 backup;
}

Burada 10.0.0.3 normal koşullarda trafik dağıtımına dahil edilmez. Ana backend sunucular uygun olmadığında yedek sunucu kullanılabilir.

SSL/TLS Terminasyonu

Nginx'i reverse proxy ve load balancer olarak kullanırken SSL/TLS bağlantısını Nginx üzerinde sonlandırabilirsiniz. Bu yöntemde istemci ile Nginx arasındaki bağlantı HTTPS olurken Nginx ile backend sunucuları arasındaki bağlantı HTTP olabilir.

Örnek HTTPS yapılandırması:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://backend;

        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;
    }
}

Bu yapıda TLS bağlantısı Nginx üzerinde sonlandırılır. Backend uygulamasının istemcinin HTTPS üzerinden bağlandığını anlayabilmesi için X-Forwarded-Proto header'ı iletilmektedir.

Backend ile Nginx arasındaki trafiğin de şifrelenmesi gerekiyorsa proxy_pass içerisinde HTTPS backend adresleri kullanılabilir:

proxy_pass https://backend;

Böylece istemci ile load balancer arasındaki bağlantının yanı sıra Nginx ile backend sunucuları arasındaki trafik de TLS üzerinden taşınabilir.

HTTP'den HTTPS'e Yönlendirme

HTTP bağlantılarını HTTPS'e yönlendirmek için ayrı bir server bloğu kullanılabilir:

server {
    listen 80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

Bu yapılandırma, HTTP üzerinden gelen istekleri aynı host ve URI korunarak HTTPS bağlantısına yönlendirir.

Pratik Nginx Load Balancing Yapılandırması

Aşağıdaki örnek, bir web uygulaması için Nginx reverse proxy ve load balancer yapılandırmasının temel bir örneğidir:

upstream web_backend {
    least_conn;

    server 10.0.0.1:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080 weight=1 max_fails=3 fail_timeout=30s;
    server 10.0.0.4:8080 backup;
}

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://web_backend;

        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_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

Bu örnekte least_conn algoritması kullanılmıştır. İlk üç backend sunucusu aktif olarak trafik alırken 10.0.0.4 adresindeki sunucu backup olarak tanımlanmıştır.

İlk iki sunucuya weight=2, üçüncü sunucuya ise weight=1 verilmiştir. max_fails ve fail_timeout değerleri ise backend sunucularda oluşabilecek bağlantı hatalarının yönetilmesine yardımcı olur.

Nginx Yapılandırmasını Test Etme

Nginx yapılandırmasında değişiklik yaptıktan sonra servisi yeniden başlatmadan önce yapılandırmanın sözdizimini kontrol etmek önemlidir:

sudo nginx -t

Yapılandırma başarılıysa Nginx'i yeniden yükleyebilirsiniz:

sudo systemctl reload nginx

Nginx servisinin durumunu kontrol etmek için:

sudo systemctl status nginx

Backend sunucuların doğru şekilde çalıştığını test etmek için load balancer üzerinden HTTP isteği gönderebilirsiniz:

curl -I http://example.com

Backend sunuculardan birini geçici olarak devre dışı bırakıp isteklerin diğer sunuculara yönlendirildiğini test etmek de failover yapılandırmasının doğrulanması açısından faydalıdır.

Load Balancing Kullanırken Dikkat Edilmesi Gerekenler

  • Backend sunucuların uygulama sürümleri ve yapılandırmaları mümkün olduğunca aynı olmalıdır.

  • Session kullanan uygulamalarda merkezi session storage veya uygun bir session yönetim stratejisi kullanılmalıdır.

  • Health check yalnızca sunucunun TCP bağlantısını değil, mümkünse uygulamanın gerçekten çalıştığını da değerlendirecek şekilde tasarlanmalıdır.

  • Nginx'in arkasındaki gerçek istemci IP'sinin uygulamaya doğru şekilde aktarılması için proxy header'ları yapılandırılmalıdır.

  • SSL/TLS sertifikaları düzenli olarak yenilenmeli ve yalnızca güncel TLS protokolleri kullanılmalıdır.

  • Load balancer'ın kendisi de yüksek kullanılabilirlik gereksinimlerine göre yedekli tasarlanmalıdır. Tek bir Nginx sunucusu tüm sistem için single point of failure oluşturabilir.

Sonuç

Nginx Load Balancing, web uygulamalarının artan trafik yükünü birden fazla backend sunucusuna dağıtmak, performansı iyileştirmek ve yüksek kullanılabilirlik sağlamak için güçlü bir çözümdür.

Nginx'in Round Robin, Least Connections, IP Hash ve Weighted Load Balancing gibi yöntemleri farklı trafik senaryolarına uyum sağlar. Bunun yanında backup, max_fails ve fail_timeout gibi özellikler backend sunuculardaki problemlerin yönetilmesine yardımcı olur.

Doğru load balancing algoritmasının seçilmesi; backend sunucuların kapasitesi, uygulamanın çalışma modeli, bağlantı süreleri ve session yönetimi gibi faktörler dikkate alınarak yapılmalıdır. Doğru planlanmış bir Nginx reverse proxy ve load balancer mimarisi, web uygulamalarının daha ölçeklenebilir, dayanıklı ve güvenilir hale gelmesine yardımcı olur.

Açık kaynak

GitHub projeleri

Tümünü gör
wireguard-server-panel

WireGuard VPN sunucu paneli - İstemci yönetimi, QR kodları ve trafik istatistikleri için kendi sunucunuzda barındırılan web kullanıcı arayüzü (fork, aktif olarak geliştirilmekte)

Go

Laravel-NDFirewall

Rota Kapsamlı Laravel WAF - RCE, SQLi, XSS ve SSRF algılama özelliklerine sahip hafif bir Web Uygulaması Güvenlik Duvarı

PHP

Trustsslroot

Tek komutla çalışan özel PKI oluşturucu - Kendi kendini imzalayan kök CA ve sertifikaları anında oluşturun

Go

node_exporter

Hafif sistem metrikleri aktarıcısı - Güvenli erişim kontrolüne sahip, Linux için durum bilgisi barındırmayan tek ikili dosyalı izleme hizmeti

Rust

ipReconary

IP keşif ve alt ağ analiz aracı - Hızlı ağ taraması ve IP istihbarat toplama

Rust

Cloudfiltred

Cloudflare IP beyaz liste güvenlik duvarı - 80/443 numaralı bağlantı noktalarını yalnızca Cloudflare IP’leriyle sınırlayarak kaynak sunucunuzu doğrudan saldırılara karşı koruyun

Rust

LoadAlertTracker

Hafif sistem yükü izleme arka plan programı - Eşik değerleri aşıldığında Telegram, Discord ve Mattermost üzerinden gerçek zamanlı uyarılar

Rust

ctCertWatch

Sertifika Şeffaflığı günlüğü izleyicisi - Kimlik avı alan adlarını, marka taklitçiliğini ve yetkisiz SSL sertifikalarını gerçek zamanlı olarak tespit eder

Rust

DDNS-FW

Dinamik DNS Güvenlik Duvarı - DDNS aracılığıyla değişen IP adreslerini takip edin ve güvenli erişim kontrolü için güvenlik duvarı kurallarını otomatik olarak güncelleyin

Rust