Mengaktifkan Nginx FastCGI Cache

Sebenarnya pas membahas Varnish untuk mengcache halaman website secara penuh tidaklah perlu dilakukan kalau menggunakan Nginx. Setidaknya bisa kita hindari lah menginstall paket aplikasi lainnya. Ini disebabkan dalam Nginx sendiri ada sistem cache serupa yakni FastCGI Cache atau kadang disebut juga microcache.

Tutorial kali ini memanfaatkan WordPress, jadi ada beberapa hal yang nanti lebih fokus kesana. Tidak banyak bedanya kalau saya perhatikan konfigurasi akhirnya misal dengan website berbasis PHP+MySQL biasa.

Pertama mari kita buat direktori untuk menyimpan cachenya:

mkdir /usr/share/nginx/cache

Ada yang bilang tahap ini tidak diperlukan karena nanti akan dibuat otomatis oleh Nginx asal lokasi direktorinya telah dimasukkan dalam konfigurasi. Tinggal restart katanya. Ini belum saya ujicoba benar tidaknya, sudah kebiasaan soalnya. 🙂 Ternyata tidak bisa, Nginx langsung error kalau direktorinya tidak ada. Yak, satu mitos sudah terpecahkan. Haha. 😀

Kemudian kita edit konfigurasi virtual host Nginx:

nano /etc/nginx/sites-available/servernesia.com

Dan tambahkan kode berikut diatas blok server {}:

fastcgi_cache_path /usr/share/nginx/cache/ levels=1:2 keys_zone=microcache:10m max_size=256m inactive=1h;
add_header X-Cache $upstream_cache_status;

Alternatifnya bisa anda masukkan kedalam konfigurasi Nginx (/etc/nginx/nginx.conf) tapi letakkan dibawah blok http {}. Ini terserah anda, tapi saya lebih suka diaktifkan per virtual host biar tidak bingung nantinya.

Lanjutkan scroll kebawah sampai anda menemukan setting untuk proses PHP-FPMnya (location ~ \.php$ {}), dan isikan dengan kode berikut:

fastcgi_cache  microcache;
fastcgi_cache_key $scheme$host$request_uri$request_method;
fastcgi_cache_valid 200 301 302 30s;
fastcgi_cache_use_stale updating error timeout invalid_header http_500;

fastcgi_pass_header Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

fastcgi_cache_bypass $tanpa_cache;
fastcgi_no_cache $tanpa_cache;

Letakkan setelah kode yang sudah ada di dalam blok tersebut ya.

Akhirnya kita tambahkan sedikit peraturan soal pengunjung yang mana akan dilayankan cachenya dan tentu saja yang sudah login jangan diberi cache. Letakkan dalam blok location / {}:

set $tanpa_cache 0;

if ($request_method != GET){
    set $tanpa_cache 1;
}

if ($query_string != ""){
    set $tanpa_cache 1;
}

if ($request_uri ~* "/(wp-login.php|wp-admin|login.php|backend|admin)"){
    set $tanpa_cache 1;
}

if ($http_cookie ~* "PHPSESSID"){
    set $tanpa_cache 1;
}

if ($http_cookie ~* "wordpress_logged_in_"){
    set $tanpa_cache 1;
}

Bila sudah maka reload/restart Nginx:

service nginx reload

Tahu darimana kita kalau FastCGI cachenya sudah berhasil aktif? Tentu saja dengan mengecek headernya saat halaman situsnya diakses:

curl -X GET -I https://servernesia.com/

Balasannya akan seperti berikut:

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 08 Apr 2016 22:30:15 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Cache: HIT

Yeah… sukses sudah. Haha. 😀 Kalau tulisannya X-Cache adalah HIT berarti sudah ada cachenya dan kalau MISS berarti belum, tinggal anda reload halaman websitenya biasanya langsung ditambahkan ke cache.

Mau cara tes yang lebih brutal? Setelah anda mengakses beberapa halaman kemudian matikan PHP-FPMnya. 😛 Serius, kalau memang sudah aktif maka bisa dilayankan langsung dari Nginx tanpa perlu memanggil mesin PHP. Jelas lebih ringan lagi performa VPS anda kalau tidak perlu memproses PHP. 🙂

Sedikit catatan, kadang bermasalah pada permalink dan atau login pengguna. Ini karena yang dicache salah atau tidak dideteksi adanya cookie. Karena itulah sistem cache seperti ini paling cocok diterapkan pada jenis pengunjung yang hanya membaca tanpa komentar, dan ini rasionya cukup besar pastinya. Bandingkan saja angka analytics anda dengan berapa banyak komentar yang masuk. 🙂

*Inspirasi panduan kali ini dari mbak Shafira dan mas Aziz yang dengan setia menanyakan soal optimasi dan cache Nginx. 😀 Dan saya lupa kalau ada satu-dua blog WordPress yang sudah menggunakannya, baru ketemu notepadnya. 😛

31 Comments

    1. Iya mbak, perlu disetting lagi agar mengenali pengunjungnya ini dilayankan konten dari FastCGI cache atau langsung dari PHP-FPM.

      Kalau ga salah istilahnya cache-busting supaya cachenya otomatis dihapus kalau ada versi konten yang lebih baru, entah diedit atau ada posting baru misalnya.

  1. mas chandra mohon infonya untuk baris berikut :

    keys_zone=microcache:10m max_size=256m inactive=1h;
    

    maksudnya maksimal ukuran folder cache 256mb dan dicache selama 1 jam?

    dan baris berikut :

    fastcgi_cache_valid 200 301 302 30s;
    

    terima kasih mas, maaf merepotkan.

    1. Hampir tepat mbak, saya jelaskan dulu:

      • keys_zone=microcache:10m ini artinya nama zona memori: microcache dan besar cache per item maksimal 10MB.
      • max_size=256m maksudnya ukuran cache total sebesar 256MB. Saya beri nilai segitu karena rata – rata VPS yang disewa 512MB. Takutnya ada yang copas dan komplain memorinya habis gara – gara ini mbak. 🙂 Kalau pribadi sih saya pakai 512MB minimal. Tapi sudah beda penggunaan lah, trafiknya lain soalnya.
      • inactive=1h sedangkan yang ini menandakan kalau cache tersebut tidak diakses selama 1 jam maka akan dibersihkan.
      • fastcgi_cache_valid ini menginstruksikan Nginx bahwa FastCGI cache ini hanya diterapkan pada kode HTTP tersebut. Kode 200 itu artinya OK mbak, berarti konten bisa diakses. Yang lainnya redirect.
  2. masalah gagal login dan logout sementara solved dengan tambahan baris kode berikut, siapa tahu membantu untuk yang menggunakan xenforo juga 🙂

        ### fastCgi cache
        set $no_cache 0;
        if ($request_method = POST) {
        set $no_cache 1;
        }
        if ($http_cookie ~* (xf_session_admin|xf_user|xf_user_admin)) {
        set $no_cache 1;
        }
        if ($request_uri ~* "/admin.php|/login/|/account/|/conversations/|/misc/|/online/") {
        set $no_cache 1;
        }
        ### fastCgi end
    1. Sep, terimakasih mbak buat tambahan informasinya. 🙂 Ada perbedaan yang dirasakan setelah menggunakan FastCGI cache mbak? Sudah coba mematikan PHP-FPMnya? 😛

      *Sudah saya koreksi juga kodenya.

      1. perbedaannya memang agak lebih kenceng mas 🙂 nah untuk matikan php-fpmnya saya belum berani hahaha :p
        cuma masalahnya saat berikan like pada komentar atau memberikan komentar tidak langsung muncul karna cachenya saya atur 5menit jadi saya coba ubah ke 1detik lumayan jadi bisa sedikit realtime jadinya tapi mungkin nggak berguna kalau dikasih waktu 1detik hahaha 😀 maunya ini cache hanya untuk guest saja, bagi yg sudah login ndak perlu diaktifkan cachenya.

      2. Kalau 1 detik apa ga terlalu cepat mbak? Efeknya mungkin terasa kalau trafiknya puluhan/ratusan per detik. Sudah bisa bedain member dan guest? Baca cookie harusnya.

  3. ups mas chandra tolong revisi baris kode diatas 😀

        ### fastCgi cache
        set $no_cache 0;
        if ($request_method = POST) {
        set $no_cache 1;
        }
    1. Secara fungsi tampaknya sangat membantu buat membersihkan cache FastCGInya. Tapi saya baca – baca tampaknya lebih diarahkan ke instalasi Nginx dari EasyEngine karena pembuatnya sama. Mungkin cuma butuh penyesuaian kalau kita pakai Nginx dari repository biasa sih, minimal lokasi direktori cachenya yang perlu disetting.

      Mas Hardinal sudah coba?

  4. Iya Mas Chandra, setelah saya baca tutorial ini, saya coba praktek.

    Ternyata plugin itu ga ngaruh. Jika ada postingan baru, maka cache nya akan di purge dan postingan baru akan masuk Homepage.

    Saya coba “cara ekstrim” saran mas, dengan mematikan PHP selama beberapa saat. Ternyata benar mas, web tetap lancar di akses.

    1. Iya mas, saya kira sih cuma sebagai pengaman ganda kalau cachenya gagal dibusting otomatis lewat Nginx. Jadi diinstruksikan lewat PHP.

      Mas coba tes kalau ada komentar baru apakah langsung diperbarui cachenya, kalau sering ada komentar biasanya yang dikhawatirkan adalah cache lama yang dilayankan.

      Haha. 😀 Ya saya usulkan tes sadis itu karena ada cara teknis tapi cuma melihat status header, kadang ga kerasa apa manfaatnya kalau dari sini. Coba kalau dimatikan PHP-FPMnya, pasti tahu apa fungsinya dan apakah berhasil tidak. 😛

  5. Halo mas Chandra, saya pengguna wordpress with easyengine.

    Pertanyaannya adalah ketika saya mengupdate artikel pada wordpress saya, apakah yg dimunculkan di homepage/category/tag dll untuk nonregistered visitor tetap akan ditampilkan versi cache atau new version.? Jika yg ditampilkan tetap versi cache bagaimana solusinya mas.? Apakah harus clear secara manual di /usr/share/nginx/cache pakai command rm -r /usr/share/nginx/cache/*

    Terimakasih atas bantuannya 🙂

  6. Jumpa lagi mas Chandra,
    Setelah saya menggunakan fastcgi sesuai aturan diatas dan memang hasilnya sangat memuaskan sekali, penggunaan cpu selalu dibawah 50%.
    Sedang yg mau saya tanyakan sekarang ialah saya mempunyai problem di webmaster dengan banyaknya “error 404 nginx” dan tentunya berkaitan dengan cache yg saya praktekkan.

    Pada saat saya nonaktifkan cache dengan cara menghapus semua konfigurasi cachenya ternyata halamannya bisa diakses dengan normal, namun setelah saya aktifkan lagi cachenya halaman jadi 404.

    Halaman yg eror ialah yg memiliki query string pada kategory dan tag, contohnya domaindotcom/tag/server/?orderby=new
    Sedangkan untuk domaindotcom/orderby=new tetap normal dan tidak ada masalah.
    Saya sudah coba pakai tutorial ini =>> https://servernesia.com/2591/membuat-nginx-fastcgi-cache-mengabaikan-query-string/ namun tetap tidak bisa 🙁

  7. Maaf begini maksudnya :
    Halaman yg eror ialah yg memiliki query string pada kategory dan tag, contohnya domaindotcom/tag/server/?orderby=new
    Sedangkan untuk domaindotcom/?orderby=new tetap normal dan tidak ada masalah.

    1. Jadi yang khusus ada query stringnya dari yang valid jadi 404 mas?

      Coba dibypass saja, tambahkan kode berikut:

      if ($request_method = POST) {
              set $tanpa_cache 1;
      }
  8. Hi, mas.
    Sudah mengikuti tutorial diatas, tapi setelah saya

    service nginx reload
    
    Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.

    FYI, kalau

    ee stack restart

    Hasilnya:

    PHP7.0-FPM is not installed
    Postfix is not installed
    Restart : nginx     [Failed]
    Restart : php5.6-fpm[OK]
    Restart : mysql     [OK]
  9. sore mas chandra,
    gimana cara bersihkan manual file cache dari fastcgi mas?
    apakah ada tools seperti opcache yang punya fitur buat nge- flush cache?
    trims.

  10. mas chandra saya ada kesulitan nih untuk cms wordpress, saya menambahkan

    location / {
    set $tanpa_cache 0;
    
    if ($request_method != GET){
        set $tanpa_cache 1;
    }
    
    if ($query_string != ""){
        set $tanpa_cache 1;
    }
    
    if ($request_uri ~* "/(wp-login.php|wp-admin|login.php|backend|admin)"){
        set $tanpa_cache 1;
    }
    
    if ($http_cookie ~* "PHPSESSID"){
        set $tanpa_cache 1;
    }
    
    if ($http_cookie ~* "wordpress_logged_in_"){
        set $tanpa_cache 1;
    }
    }

    hasilnya nginx: [emerg] duplicate location "/" soalnya ada ini juga di vhost.d/wp.conf

            location / {
                    try_files $uri $uri/ /index.php;
                    if ($request_uri ~* index/$){
                    rewrite ^/(.*)/index/$ /$1 permanent;
                    }

    gimana ya solusinya mas?

    1. Coba digabungkan mas:

              location / {
                      try_files $uri $uri/ /index.php;
                      if ($request_uri ~* index/$){
                      rewrite ^/(.*)/index/$ /$1 permanent;
                      }
      set $tanpa_cache 0;
      
      if ($request_method != GET){
          set $tanpa_cache 1;
      }
      
      if ($query_string != ""){
          set $tanpa_cache 1;
      }
      
      if ($request_uri ~* "/(wp-login.php|wp-admin|login.php|backend|admin)"){
          set $tanpa_cache 1;
      }
      
      if ($http_cookie ~* "PHPSESSID"){
          set $tanpa_cache 1;
      }
      
      if ($http_cookie ~* "wordpress_logged_in_"){
          set $tanpa_cache 1;
      }
      }
      
    1. Kontennya tidak dicache mas.

      Kalau ini file statis (js, css, gambar, dan sebagainya). Ini perlu disetting lagi expirationnya.

Tinggalkan Balasan ke shafira Batalkan balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *