Bagaimana cara mengatur Nginx sebagai caching reverse proxy?

143

Saya mendengar baru-baru ini bahwa Nginx telah menambahkan caching ke fitur proxy terbalik. Saya melihat sekeliling tetapi tidak menemukan banyak info tentang itu.

Saya ingin mengatur Nginx sebagai caching reverse proxy di depan Apache / Django: untuk memiliki permintaan proxy Nginx untuk beberapa (tetapi tidak semua) halaman dinamis ke Apache, kemudian cache halaman yang dihasilkan dan melayani permintaan berikutnya untuk halaman tersebut dari cache.

Idealnya saya ingin membatalkan cache dengan 2 cara:

  1. Tetapkan tanggal kedaluwarsa pada item yang di-cache
  2. Untuk secara eksplisit membatalkan item yang di-cache. Misalnya jika backend Django saya telah memperbarui data tertentu, saya ingin memberitahu Nginx untuk membatalkan cache dari halaman yang terpengaruh

Apakah mungkin untuk mengatur Nginx untuk melakukan itu? Bagaimana?

Kelanjutan
sumber
Tidak diuji, tetapi dari gumroad.com/l/ngx_purge : "ngx_purge adalah modul Lua murni untuk Nginx yang memungkinkan pengguna untuk membersihkan objek dari cache nginx.".
Jaime Hablutzel

Jawaban:

97

Saya tidak berpikir bahwa ada cara untuk secara eksplisit membatalkan item yang di-cache, tetapi di sini adalah contoh bagaimana melakukan sisanya. Pembaruan: Seperti yang disebutkan oleh Piotr dalam jawaban lain, ada modul pembersih cache yang bisa Anda gunakan. Anda juga dapat memaksa penyegaran item yang di-cache menggunakan proxy_cache_bypass dari nginx - lihat jawaban Cherian untuk informasi lebih lanjut.

Dalam konfigurasi ini, item yang tidak di-cache akan diambil dari example.net dan disimpan. Versi yang di-cache akan disajikan hingga klien masa depan hingga tidak lagi valid (60 menit).

Kontrol Cache dan Kedaluwarsa HTTP header Anda akan dihormati, jadi jika Anda ingin secara eksplisit menetapkan tanggal kedaluwarsa, Anda dapat melakukannya dengan mengatur header yang benar dalam apa pun yang Anda proksi.

Ada banyak parameter yang dapat Anda sesuaikan - lihat dokumentasi modul Proxy nginx untuk informasi lebih lanjut tentang semua ini termasuk rincian tentang arti pengaturan / parameter yang berbeda: http://nginx.org/r/proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}
Casey
sumber
7
Ini adalah langkah pertama yang masuk akal untuk aplikasi baru yang tidak memiliki 20 k / req / s.
5
@ Larry, apa yang akan menjadi langkah kedua?
Jürgen Paul
42
@ Legit - Saya tidak tahu, tetapi secara tradisional langkah terakhir adalah "Untung" :-)
Stephen C
Sayangnya, ini tidak bekerja dengan nginx 1.11. Karena pembaruan terakhir sekitar 3 tahun yang lalu, sepertinya ini bukan lagi solusinya.
izogfif
Apa inactive=600mmaksud dari: Bukankah inactiveseharusnya waktu? `[inactive=time]
NeverEndingQueue
47

Anda dapat secara khusus membatalkan halaman tembolok

proxy_cache_bypass       

Katakanlah Anda ingin me-cache halaman, atur cache dengan cara ini

location = /pageid {
  proxy_pass http://localhost:82;
  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_ignore_headers Set-Cookie; 
  proxy_ignore_headers Cache-Control; 
  proxy_cache_bypass        $http_secret_header;
  add_header X-Cache-Status $upstream_cache_status;
}

Sekarang, ketika Anda ingin membatalkan halaman itu dan cache lagi

Lakukan panggilan ikal rahasia dengan tajuk

curl "www.site.com/pageid" -s -I -H "secret_header:true" 

Ini akan membatalkan dan menyimpannya.

Bekerja dari nginx 0.7.

Sebagai bonus tambahan, add_header X-Cache-Statusdapat digunakan untuk memeriksa apakah halaman tersebut dari cache atau tidak.

Cherian
sumber
Ini hanya dapat memperbarui halaman yang di-cache ketika halaman baru juga bisa di-cache. Jika Anda telah menghapus halaman (404 atau kesalahan lainnya sekarang dilayani oleh backend), halaman tersebut sekarang mengirimkan header Set-Cookie atau header "Content-Control: private", konten yang di-cache tidak akan "tidak valid".
rbu
36

Saya sarankan Anda mencoba Varnish . Varnish dirancang khusus sebagai cache proksi terbalik. Ini akan menghormati semua header kontrol cache yang Anda kirim dari server asal, yang memenuhi permintaan pertama Anda.

Untuk permintaan kedua Anda, pembatalan eksplisit. Rekomendasi kuat saya adalah untuk mengubah nama url dari sumber daya yang ingin Anda batalkan, baik dengan mengganti nama file atau menggunakan beberapa bentuk buster cache string kueri. Varnish memang memiliki PURGEoperasi yang akan menghapus sumber daya dari cache Varnish, tetapi tidak akan memberi Anda kontrol atas cache lain antara Anda dan pengguna. Seperti yang Anda katakan ingin menghapus sumber daya secara eksplisit, maka header kontrol http standar tidak akan membantu Anda. Dalam kasus itu, cara yang paling mudah untuk mengalahkan caching sumber daya adalah dengan mengganti namanya.

Dave Cheney
sumber
Bisakah Anda menjelaskan apa yang Anda maksud dengan "mengganti nama file atau menggunakan beberapa bentuk cache string cache query"? Saya tidak yakin saya mengerti mengapa itu bukan ide yang baik untuk menggunakan operasi seperti PURGE.
Lanjutan
5
+1 untuk pernis. Selalu jauh lebih baik menggunakan alat yang tepat untuk pekerjaan itu.
Tom O'Connor
4
@ di bawah: Hampir tidak ada harapan untuk menyentuh pernis di arena pertunjukan dan keserbagunaan. Ini didukung oleh salah satu pengembang kernel FreeBSD dan tim khusus yang berbasis di Eropa. Varnish diproduksi di twitter, heroku, dan banyak lagi.
2
Contoh paling sederhana dari cache-buster adalah menambahkan nomor versi dalam string kueri ke sumber daya statis, sehingga style.css menjadi style.css? 123. Ketika Anda ingin mendorong versi baru file, Anda mengubah url sumber daya ke style.css? 124 dan sekarang cache akan mengambilnya sebagai aset yang sama sekali baru untuk di-cache secara terpisah. Apache akan menyajikan file style.css dengan string kueri apa pun yang ditambahkan, jadi tidak diperlukan perubahan pada file yang sebenarnya.
chmac
3
Jika memungkinkan, yang terbaik adalah menempatkan buster cache ke nama file itu sendiri, seperti style.v123.csskarena beberapa cache tidak akan menembolok permintaan yang memiliki string kueri.
Noah McIlraith
8

Untuk membatalkan halaman yang dipilih, Anda dapat menggunakan patch "cache_purge" untuk nginx-0.8.x yang memang sesuai dengan yang Anda inginkan;)

Ini tersedia di sini .


sumber
8

Sebagian besar alat cache (Citrix) memungkinkan pemuatan paksa (Ctrl + r) untuk mengisi kembali halaman yang di-cache.

Inilah trik yang saya temukan untuk melakukan hal serupa di nginx.

server  {
        # Other settings
        proxy_pass_header       Set-Cookie; # I want to cache logged-in users
        proxy_ignore_headers    X-Accel-Redirect;
        proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
        if ($http_cache_control ~ "max-age=0") {set $eac 1;}
        proxy_cache_bypass $eac;
}

Ini mengasumsikan bahwa ketika Anda melakukan Ctrl + r di browser Anda, header Cache-Control memiliki max-age = 0 dalam permintaannya. Saya tahu Chrome melakukan ini, tetapi saya belum mencoba di peramban lain. Menambahkan lebih banyak bidang tajuk bisa mudah, hanya dengan menambahkan lebih banyak jika pernyataan yang mengatur $eacvariabel menjadi 1.

Randy Wallace
sumber
5

Caching adalah fungsi yang cukup baru di nginx (dan belum didokumentasikan dengan baik untuk saat ini), tetapi cukup stabil untuk digunakan dalam produksi.

SaveTheRbtz
sumber
4

Saya percaya NginxHttpProxyModule mampu membuat permintaan http caheing. Cari arahan yang dimulai dengan:

proxy_cache

Ya, adalah mungkin untuk mengontrol perilaku cache melalui arahan seperti:

proxy_cache_valid
Taras Chuhay
sumber
3

Berdasarkan fakta bahwa Anda tidak dapat menemukan dokumen di atasnya, saya akan sedikit khawatir tentang mengandalkannya dalam produksi. Sudahkah Anda mempertimbangkan Varnish? Ini adalah "nginx of reverse proxies" saya, kecil, ringan, melakukan satu pekerjaan dan melakukannya dengan baik.

womble
sumber
Dokumentasi di sini: wiki.nginx.org/NginxHttpProxyModule#proxy_cache
rmalayter
2

Jika Anda menggunakan eTag pada aplikasi Anda dan meletakkan nginx di depannya maka itu akan menyelesaikan masa berlaku Anda, karena jika eTag berubah maka akan membatalkan cache.

Martin Murphy
sumber
Benarkah? Tampaknya ngnix cocok dengan etag dan tidak pernah berbicara dengan aplikasi untuk mencari tahu apakah ada etag yang diperbarui.
John Naegle
2

Anda dapat mengontrol kedaluwarsa cache Nginx dengan beberapa arahan / parameter:

  • proxy_cache_valid 200 302 10m;
  • menambahkan salah satu tajuk HTTP di bawah ini (prioritas penting - lihat posting blog saya ):
    • Expires
    • Cache-Control
    • X-Accel-Expires
  • yang inactiveparameter dalam proxy_cache_pathdirektif:

    proxy_cache_path /data/nginx/cache keys_zone=one:10m inactive=60m;

Saya merekomendasikan posting blog saya jika Anda ingin mempelajari lebih lanjut tentang caching Nginx.

Topik pembersihan sangat menarik karena fitur ini hanya ada di Nginx Plus (edisi komersial Nginx). Saya sangat suka jawaban @ randy-wallace. Tetapi ada juga kemungkinan lain seperti modul ngx_cache_purge .

Hal paling sederhana yang dapat Anda lakukan adalah menghapus file cache secara manual:

  • buat kunci hash Anda:

    echo -n ‘httpczerasz.com/time.php’ | md5sum
    
  • hapus file dari sistem file:

    rm /data/nginx/cache/1/27/2bba799df783554d8402137ca199a271
    
Czerasz
sumber
1

Untuk pengunjung masa depan: Sementara itu proksi nginx reverse memiliki caching terintegrasi dan dokumen tersedia di:

Sintaksis: proxy_cache zone | mati;

Default: proxy_cache off;

Konteks: http, server, lokasi

Menentukan zona memori bersama yang digunakan untuk cache. Zona yang sama dapat digunakan di beberapa tempat. Nilai parameter dapat berisi variabel (1.7.9). Parameter tidak aktif menonaktifkan caching yang diwarisi dari tingkat konfigurasi sebelumnya.

Tarik Huclaslun
sumber
Hai Tarik, pertanyaannya sangat spesifik tentang apa yang perlu dicapai, dan itu sedikit di luar dari 'hanya aktifkan cache'.
asdmin
0
fastcgi_cache_path / opt / nginx-cache levels = 2: 2 keys_zone = img: 50m;

    lokasi / img / {
        fastcgi_pass $ backend;
        termasuk fcgi_params;
        mati fastcgi_intercept_errors;   
        fastcgi_cache_key $ server_addr $ request_uri;       
        fastcgi_cache img;
        fastcgi_cache_valid 1m;
        fastcgi_hide_header Set-Cookie;
    }

Ini menciptakan cache untuk / img / lokasi. Itu ada di / opt / nginx-cache. Objek di-cache selama 1 menit.

Anda dapat menulis kode respons yang berbeda.

Sekarang Anda tidak dapat membatalkan cache untuk halaman yang dipilih. Mungkin dalam 0.8.x itu akan mungkin.

lexsys
sumber
Pertanyaan aslinya adalah tentang menggunakan nginx di depan Apache, bukan di depan aplikasi fastcgi yang ditangani oleh nginx.
Graham Dumpleton
0

Ada plugin nginx bernama ncache yang mengklaim sebagai "sistem cache web berbasis server web nginx. Lebih cepat dan lebih efisien daripada squid."

sajal
sumber