Blok upstream
upstream backend {
server 10.0.1.10:3000 weight=3;
server 10.0.1.11:3000 weight=1;
server 10.0.1.12:3000 backup;
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Metode Pembagian Beban
upstream backend {
# round robin — bawaan, tanpa perlu ditulis
server a:3000;
server b:3000;
}
upstream backend {
least_conn; # ke server dengan koneksi aktif paling sedikit
server a:3000;
}
upstream backend {
ip_hash; # klien yang sama selalu ke server yang sama
server a:3000;
}
upstream backend {
hash $request_uri consistent; # berdasarkan URI, cocok untuk cache
server a:3000;
}
least_conn biasanya pilihan paling aman ketika durasi permintaan bervariasi — round robin membagi rata jumlah permintaan, bukan beban sesungguhnya, sehingga satu server bisa menumpuk permintaan berat sementara yang lain menganggur.
ip_hash sering dipakai agar sesi login tetap menempel di satu server. Masalahnya: menambah atau menghapus satu server mengubah pemetaan untuk sebagian besar klien sehingga sesi hilang serentak. Klien di belakang NAT perusahaan juga menumpuk ke satu server yang sama. Menyimpan sesi di Redis jauh lebih tahan banting.
keepalive: Penyetelan Kecil, Dampak Besar
Tanpa keepalive, Nginx membuka koneksi TCP baru ke hulu untuk setiap permintaan lalu menutupnya. Pada lalu lintas tinggi, biaya jabat tangan TCP dan port yang menumpuk di keadaan TIME_WAIT menjadi hambatan nyata.
Menulis keepalive 32 saja tidak cukup. Nginx berbicara HTTP/1.0 ke hulu secara bawaan dan tetap mengirim header Connection: close. Dua direktif ini wajib menyertainya:
proxy_http_version 1.1; proxy_set_header Connection "";
Tanpa keduanya, angka keepalive tidak berpengaruh sama sekali dan koneksi tetap dibuat-tutup setiap permintaan.
Menyingkirkan Server Bermasalah
upstream backend {
server 10.0.1.10:3000 max_fails=3 fail_timeout=30s;
server 10.0.1.11:3000 max_fails=3 fail_timeout=30s;
}
Ini pemeriksaan pasif: setelah 3 kegagalan dalam rentang 30 detik, server ditandai tidak sehat dan dilewati selama 30 detik berikutnya, lalu dicoba lagi. Nginx sumber terbuka tidak memiliki pemeriksaan aktif — fitur itu hanya ada pada Nginx Plus atau modul pihak ketiga.
Mengulang ke Server Lain
proxy_next_upstream error timeout http_502 http_503; proxy_next_upstream_tries 2; proxy_next_upstream_timeout 10s;
Secara bawaan Nginx tidak mengulang permintaan POST, PATCH, atau LOCK ke server lain — dan itu disengaja. Bila hulu sudah menerima serta memproses POST /pembayaran lalu gagal saat mengirim balasan, mengulangnya ke server lain berarti pembayaran diproses dua kali. Menambahkan non_idempotent hanya aman bila endpoint benar-benar melindungi diri dengan kunci idempoten.
Resolusi DNS yang Berubah
resolver 10.0.0.2 valid=30s ipv6=off;
location / {
set $hulu "layanan.internal:3000";
proxy_pass http://$hulu;
}
Nama host di dalam proxy_pass diselesaikan sekali saat startup dan tidak pernah diperiksa lagi. Di Kubernetes atau lingkungan dengan IP yang berpindah, Nginx akan terus mengirim ke alamat yang sudah mati sampai di-reload. Memakai variabel memaksa Nginx menyelesaikan DNS saat permintaan datang, mengikuti valid= pada resolver.