Chapter DNS Server memberi nama pada alamat server kita; sekarang kita atur siapa yang menjawab ketika nama itu dipanggil. Reverse proxy adalah lapisan yang berdiri paling depan: satu pintu yang menerima seluruh permintaan dari klien, lalu meneruskannya ke aplikasi di belakangnya. Dengan pola ini, satu alamat publik bisa melayani banyak aplikasi, membagi beban ke beberapa instance, dan menangani TLS di satu tempat. Mesin latihan kita tidak memasang Nginx, jadi file konfigurasi kita bedah lewat fixture, sementara logika pembagian beban kita uji sungguhan dengan dua server lokal di loopback.
Forward Proxy versus Reverse Proxy #
Kata proxy berarti perantara, dan arah perantara itulah yang membedakan keduanya. Forward proxy berdiri di sisi klien: browser kantor yang meneruskan permintaan ke internet lewat proxy, sehingga server tujuan hanya melihat alamat proxy, bukan alamat klien. Reverse proxy kebalikannya — berdiri di sisi server, menyambut klien yang datang lalu menghubungi backend atas nama klien. Perbandingan keduanya:
| Aspek | Forward proxy | Reverse proxy |
|---|---|---|
| Mewakili | klien | server / backend |
| Dipasang oleh | pihak klien (kantor, ISP) | admin server |
| Terlihat oleh klien | ya, eksplisit dikonfigurasi | tidak — terasa seperti server biasa |
| Contoh klasik | proxy sekolah, cache ISP | pintu depan situs besar |
Di mata klien, reverse proxy memang tak terlihat: curl ke alamat situs terasa seperti menyapa satu server, padahal jawaban bisa datang dari salah satu dari sepuluh mesin di belakangnya.
Empat Pekerjaan yang Diembankan pada Reverse Proxy #
Pola satu pintu depan ini dipakai untuk empat pekerjaan yang berulang di dunia server. Pertama, TLS termination: sertifikat dan negosiasi enkripsi cukup dikelola di satu tempat, sementara backend berbicara polos di jaringan internal — pengelolaan sertifikatnya sendiri kita bahas tuntas di Chapter TLS dan SSL Certificates
. Kedua, load balancing: permintaan dibagi ke beberapa instance aplikasi agar tidak ada satu mesin yang kewalahan. Ketiga, caching dan kompresi: jawaban yang sering diminta bisa disimpan di depan, dan respons dikompresi sekali untuk semua klien. Keempat, melindungi backend: aplikasi cukup mendengarkan di 127.0.0.1, tidak pernah tersentuh internet secara langsung, sehingga permukaan serangan menyempit dan backend bisa direstart tanpa klien sadar.
proxy_pass: Meneruskan Permintaan ke Backend #
Di Nginx — yang server block dan direktori konfigurasinya sudah kita kenal dari Chapter nginx
— seluruh pekerjaan reverse proxy berpusat pada satu directive: proxy_pass. Fixture reverse-proxy.conf di bundle chapter ini memperlihatkan konfigurasi lengkapnya:
cat reverse-proxy.confOutput yang Dihasilkan:
upstream backend.example.com {
server 127.0.0.1:8231;
server 127.0.0.1:8232;
}
server {
listen 80;
server_name app.latihan.example.com;
location / {
proxy_pass http://backend.example.com/;
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;
}
}Mari kita bedah blok demi blok:
- Blok
upstream backend.example.com: mendefinisikan kelompok backend — dua instance yang masing-masing mendengarkan di127.0.0.1port 8231 dan 8232. Nama upstream hanyalah label pilihan kita, dan menjadi satu-satunya tempat yang perlu disentuh saat daftar backend berubah. server { listen 80; server_name app.latihan.example.com; }: pintu depan yang menghadap klien — pasanganlistendanserver_namesudah kita bedah di Chapter Web Server .location / { ... }: semua path jatuh ke blok ini, sehingga seluruh permintaan diteruskan tanpa kecuali.proxy_pass http://backend.example.com/;: inti reverse proxy — Nginx membuka koneksi ke salah satu anggota upstream, mengirim permintaan, lalu mengalirkan jawabannya kembali ke klien. Tanda/di akhir membuat directive ini membawa URI: bagian permintaan yang cocok denganlocationdiganti oleh URI tersebut. Padalocation /hasilnya sama persis dengan tanpa garis miring; bentuk ber-URI baru berdampak pada location yang lebih spesifik, misalnyalocation /api/yang ingin memangkas awalan/apisebelum meneruskan.proxy_set_header Host $host;: nama domain asli tetap dikirim ke backend, agar aplikasi yang melayani banyak domain tetap tahu domain mana yang diminta.proxy_set_header X-Real-IP $remote_addr;: alamat IP klien asli — tanpa baris ini, semua permintaan yang dilihat backend datang dari127.0.0.1.proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;: rantai alamat klien; nilai$proxy_add_x_forwarded_formenambahkan alamat klien ke daftar yang sudah ada, sehingga tiap proxy yang dilalui meninggalkan jejak.proxy_set_header X-Forwarded-Proto $scheme;: memberi tahu backend skema asli permintaan,httpatauhttps— penting ketika backend menyusun URL absolut.
Load Balancing: Membagi Beban ke Banyak Backend #
Saat upstream berisi lebih dari satu server, Nginx otomatis membagi permintaan dengan round robin: bergiliran rata, backend pertama lalu kedua, kembali ke pertama, begitu seterusnya. Dua metode lain dinyalakan dengan satu baris di dalam blok upstream:
| Metode | Baris di blok upstream | Cara memilih backend |
|---|---|---|
| Round robin | tanpa baris (bawaan) | bergiliran rata ke semua anggota |
| Least connections | least_conn; | anggota dengan koneksi aktif paling sedikit |
| IP hash | ip_hash; | alamat IP klien yang sama selalu menuju anggota yang sama |
Kita buktikan giliran round robin dengan dua backend sungguhan di loopback — dua instance python3 -m http.server dengan isi berbeda:
mkdir -p backend-1 backend-2
printf 'jawaban dari aplikasi-1\n' > backend-1/index.html
printf 'jawaban dari aplikasi-2\n' > backend-2/index.html
python3 -m http.server 8231 --bind 127.0.0.1 --directory backend-1 >/dev/null 2>&1 &
pid1=$!
python3 -m http.server 8232 --bind 127.0.0.1 --directory backend-2 >/dev/null 2>&1 &
pid2=$!
for i in 1 2 3 4 5; do
curl -s -o /dev/null 127.0.0.1:8231/ && curl -s -o /dev/null 127.0.0.1:8232/ && break
sleep 0.2
done
ss -tln | grep 8231
ss -tln | grep 8232
gilir=("127.0.0.1:8231/" "127.0.0.1:8232/")
for i in 0 1 2 3 4 5; do
curl -s "${gilir[$(( i % 2 ))]}"
done
kill "$pid1" "$pid2"Output yang Dihasilkan:
LISTEN 0 5 127.0.0.1:8231 0.0.0.0:*
LISTEN 0 5 127.0.0.1:8232 0.0.0.0:*
jawaban dari aplikasi-1
jawaban dari aplikasi-2
jawaban dari aplikasi-1
jawaban dari aplikasi-2
jawaban dari aplikasi-1
jawaban dari aplikasi-2Enam baris jawaban berselang-seling itulah round robin yang dikerjakan proxy_pass pada upstream dua anggota. Mari kita bedah bagiannya:
- Baris 1-3: menyiapkan dua backend dengan isi berbeda — isi inilah identitas tiap instance saat kita membaca jawaban.
- Baris 4-7: menyalakan kedua backend sebagai background process di port berbeda; keduanya diikat ke
127.0.0.1saja, persis posisi backend di balik reverse proxy. - Baris 9-11:
ss -tlnmemastikan keduanya benar-benar mendengarkan — pola pemeriksaan dari Chapter ss dan netstat . - Baris 12 (
gilir=(...)): array dua alamat — versi shell dari blokupstream;curlmenerima alamat tanpa skema dan menganggapnyahttp. - Baris 14 (
${gilir[$(( i % 2 ))]}): jantung round robin — operator modulo%memetakan nomor permintaan ke indeks array menjadi0, 1, 0, 1, sehingga beban terbagi rata. Nginx memakai penghitung internal yang sama untuk memilih anggota upstream berikutnya. - Baris 16 (
kill ...): membereskan kedua backend setelah latihan.
Selagi giliran berjalan, Nginx juga mengawasi kesehatan anggota upstream secara pasif: setiap percobaan koneksi yang gagal dihitung. Baris berikut memberi ruang tiga kegagalan dalam 30 detik sebelum anggota dianggap tidak tersedia selama 30 detik:
server 127.0.0.1:8233 max_fails=3 fail_timeout=30s;Anggota yang sedang ditandai mati tidak menerima permintaan baru sampai masa cobaannya habis — permintaan klien tetap dilayani anggota lain tanpa satu pun error yang bocor ke luar. Dua pengaturan lanjutan yang sering menyertai tabel ini: buffering menyala bawaannya, sehingga jawaban backend ditampung dulu di memori proxy sebelum dituliskan pelan-pelan ke klien yang lambat, dan timeout — proxy_read_timeout 60s bawaannya — memutus tunggu ketika backend terlalu lama diam.
Pintu depan ini baru separuh cerita: begitu klien mengharapkan gembok HTTPS di browser, reverse proxy-lah pihak yang paling sering memegang sertifikat. Cara membuat, meminta, dan memperbaruinya adalah materi Chapter TLS dan SSL Certificates .
Referensi lanjut: dokumentasi modul proxy Nginx
untuk seluruh directive proxy_*, serta dokumentasi modul upstream
untuk pembagian beban dan health check.