Cache Proxy
http {
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=zonaku:10m
max_size=10g
inactive=60m
use_temp_path=off;
server {
location /api/ {
proxy_cache zonaku;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 301 302 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
}
}
Header X-Cache-Status sangat membantu saat menyetel: nilainya HIT, MISS, BYPASS, EXPIRED, STALE, atau UPDATING. Tanpa itu, menebak apakah cache benar-benar bekerja hampir mustahil.
Bila kunci cache tidak menyertakan identitas dan balasan bersifat personal, halaman milik pengguna A akan disajikan kepada pengguna B. Ini kebocoran data yang nyata dan pernah terjadi pada banyak situs besar. Lewati cache untuk permintaan yang membawa sesi:
proxy_cache_bypass $http_authorization $cookie_sesi; proxy_no_cache $http_authorization $cookie_sesi;
proxy_cache_bypass membuat Nginx tidak membaca dari cache; proxy_no_cache membuatnya tidak menulis ke cache. Keduanya diperlukan.
Melayani Saat Hulu Mati
proxy_cache_use_stale error timeout updating
http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
Ini salah satu konfigurasi paling berharga di Nginx. Ketika hulu tumbang, pengunjung tetap menerima versi lama alih-alih halaman galat. Dengan background_update, isi kedaluwarsa disajikan seketika sementara pembaruan berjalan di belakang layar.
Ketika satu entri populer kedaluwarsa, semua permintaan yang datang bersamaan dapat menembus ke hulu sekaligus — dikenal sebagai cache stampede. Direktif proxy_cache_lock mengizinkan hanya satu permintaan yang lewat, sementara sisanya menunggu hasilnya.
Berkas Statis
location /statis/ {
root /var/www;
sendfile on; # salin berkas di kernel, tanpa melewati userspace
tcp_nopush on; # kirim header bersama awal berkas dalam satu paket
tcp_nodelay on;
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_errors on;
expires 1y;
add_header Cache-Control "public, immutable";
}
expires 1y hanya aman untuk berkas ber-hashMenyetel setahun pada app.js berarti pengunjung lama tidak akan pernah menerima versi baru sampai cache peramban mereka dibersihkan. Ini aman hanya bila nama berkas mengandung hash isi — app.a3f9c1.js — sehingga perubahan menghasilkan nama baru. Untuk index.html gunakan no-cache agar penunjuk ke berkas ber-hash selalu segar.
Kompresi
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_proxied any;
gzip_types text/plain text/css application/json
application/javascript text/xml application/xml
image/svg+xml;
gzip_comp_level 9 memakai jauh lebih banyak CPU tetapi hanya menghemat beberapa persen ukuran dibanding level 5. Pada lalu lintas tinggi, CPU itu lebih berharga daripada selisih kecil tersebut. Level 4–6 adalah titik seimbang yang lazim.
Jangan mengompresi berkas yang sudah terkompresi — JPEG, PNG, MP4, ZIP. Hasilnya justru sedikit lebih besar sekaligus membakar CPU.
Menyajikan Berkas Terkompresi Lebih Dulu
gzip_static on; # sajikan app.js.gz bila ada, tanpa kompresi saat permintaan brotli_static on; # butuh modul brotli
Berkas dikompresi sekali saat proses build, lalu Nginx menyajikannya langsung. Kompresi tingkat maksimum menjadi masuk akal di sini karena hanya dilakukan sekali, bukan pada setiap permintaan.