Kodeloka
  1. Kodeloka
  2. Kelas Nginx
  3. Materi

1 · Fondasi · Modul 1 dari 8

Arsitektur & Model Proses

Kenapa Nginx sanggup melayani puluhan ribu koneksi dengan memori kecil, sementara server berbasis thread kewalahan.

Satu Master, Beberapa Worker

Nginx berjalan sebagai satu proses master dan sejumlah proses worker. Master tidak melayani permintaan sama sekali — tugasnya membaca konfigurasi, membuka port, dan mengelola worker. Worker-lah yang menangani seluruh lalu lintas.

ps -ef | grep nginx

root      1234  nginx: master process /usr/sbin/nginx
www-data  1235  nginx: worker process
www-data  1236  nginx: worker process
www-data  1237  nginx: worker process
www-data  1238  nginx: worker process

Master berjalan sebagai root karena hanya root yang boleh mengikat port di bawah 1024 (80 dan 443). Setelah port terbuka, worker diturunkan haknya menjadi pengguna biasa. Jadi kode yang benar-benar bersentuhan dengan lalu lintas internet tidak berjalan sebagai root.

Kenapa Bukan Satu Thread per Koneksi

Server tradisional seperti Apache dengan mode prefork memberi satu proses atau thread untuk setiap koneksi. Dengan 10.000 koneksi, itu 10.000 thread — masing-masing butuh memori stack sendiri (biasanya 1–8 MB) dan sistem menghabiskan waktu berpindah antar konteks alih-alih bekerja.

Nginx membalik modelnya. Setiap worker adalah proses single-thread yang menjalankan satu loop peristiwa. Loop itu bertanya ke kernel lewat epoll (Linux): "soket mana yang siap dibaca atau ditulis?" Kernel menjawab dengan daftar, worker melayani semuanya, lalu bertanya lagi.

💡 Koneksi menganggur nyaris gratis

Inilah inti keunggulannya. Koneksi yang sedang menunggu — keep-alive yang diam, klien dengan jaringan lambat, WebSocket tanpa lalu lintas — tidak memegang thread apa pun. Ia hanya satu entri deskriptor berkas di dalam epoll, biayanya beberapa ratus byte. Server berbasis thread membayar penuh untuk koneksi yang tidak melakukan apa-apa.

Menyetel Jumlah Worker

worker_processes  auto;          # satu per inti CPU — hampir selalu benar
worker_rlimit_nofile 65535;      # batas deskriptor berkas per worker

events {
    worker_connections  4096;    # koneksi maksimum per worker
    multi_accept        on;      # terima beberapa koneksi sekaligus
}

Kapasitas teoretisnya adalah worker_processes × worker_connections. Namun untuk reverse proxy angkanya harus dibagi dua: setiap permintaan klien memakai dua koneksi — satu ke klien, satu ke server hulu.

⚠️ worker_connections tidak berguna tanpa menaikkan batas berkas

Menulis worker_connections 65535 sementara batas sistem ulimit -n masih 1024 tidak akan menambah kapasitas apa pun. Nginx tetap kehabisan deskriptor berkas di angka 1024 dan mencatat too many open files di log kesalahan. Naikkan worker_rlimit_nofile di konfigurasi dan batas di systemd unit.

Menambah CPU tapi Nginx Tidak Ikut Cepat

Karena worker adalah single-thread, satu worker hanya bisa memakai satu inti. Bila worker_processes dikunci di angka 1 pada mesin 16 inti, 15 inti lainnya menganggur meskipun beban sudah penuh. Nilai auto menghindari jebakan ini.

Operasi Tanpa Menjatuhkan Koneksi

nginx -t                  # UJI konfigurasi — selalu sebelum reload
nginx -s reload           # muat ulang tanpa memutus koneksi
nginx -s quit             # berhenti setelah permintaan selesai
nginx -s stop             # berhenti segera

Saat reload, master membaca konfigurasi baru, menjalankan worker baru dengan konfigurasi itu, lalu meminta worker lama berhenti menerima koneksi baru dan selesai melayani yang sedang berjalan. Tidak ada permintaan yang terputus — dan bila konfigurasi baru salah, master menolaknya dan worker lama tetap melayani seperti biasa.