Tìm hiểu Caching và cách tăng tốc website trên NGINX

Được mệnh danh là webserver tốc độ cao, Nginx đã tích hợp sẵn tính năng tạo cache nội dung động (Dynamic Cache) và cache nội dung tĩnh (Browser Cache) phù hợp với nhiều hệ thống Web Server có kiến trúc khác nhau. Ngoài ra, nginx còn hỗ trợ nén nội dung với Gzip Compression trước khi gửi đến cho trình duyệt nhằm giảm bớt băng thông tải web.

Trên hết những module này đã được mặc định trong nginx, bạn không phải cài cắm thêm gì nữa chỉ việc cấu hình sử dụng thôi.

1. Tìm hiểu caching trên nginx

Đầu tiên mình phải khẳng định Nginx là một Webserver thực thụ, vì nó rất mạnh với khả năng tạo cache mà mọi người biết đến nó như một hệ thống Caching nhiều hơn.

Chúng ta cần phân biệt Proxy Cache và FastCGI Cache. Đây là 2 module khác nhau của nginx dùng để xây dựng hệ thống cache cho từng mô hình máy chủ khác nhau.

Proxy Cache dùng để cấu hình cache giao thức http, trong mô hình này nginx đứng ngoài cùng đóng vai trò làm Proxy Server hứng request từ client. Khi chạy theo mô hình này hệ thống website thường gồm ít nhất hai máy chủ, hiện có nhiều người triển khai mô hình này với Apache làm backend, cách hoạt động này cũng giống mô hình sử dụng Varnish Cache, Squid.

FastCGI Cache hoạt động theo cách thức khác, nó cache lại các response mà trình thông dịch (PHP-FPM) hoặc  Application Server khác đứng ở backend trả lại cho Webserver. Hầu hết với những website cá nhân nhỏ, người dùng thường nhồi nhét tất cả trên một server mình khuyên nên dùng FastCGI Cache là tốt nhất.

Cách hoạt động

Nội dung tiếp theo chúng ta sẽ đi vào tìm hiểu caching trên nginx làm việc thế nào áp dụng cho cả Proxy Cache hay FastCGI Cache.

Như các bạn đã biết khi User lần đầu truy cập website, webserver nginx sẽ kiểm tra trong RAM có cache lại thông tin gì mà người dùng yêu cầu hay không nếu không có nó sẽ làm việc với backend để lấy thông tin người dùng yêu cầu. Sau khi xử lý xong backend sẽ trả kết quả lại cho nginx.

Nginx cache request

 

Nhận được response từ backend nginx không gửi luôn cho User mà lưu lại trên File System một bản gọi là Cache File, đồng thời nó cũng lấy Key (Cache Key) tương ứng với mỗi cache file để lưu lên RAM sau đó mới trả kết quả lại cho User.

Lần tiếp theo người dùng truy cập website, nginx cũng kiểm tra trên RAM trước nó so sánh request tương ứng với Key nào, nếu khớp nó sẽ lấy Cache file tương ứng với Key đó trong File System rồi trả kết quả cho người dùng. Như vậy sẽ giảm bớt tài nguyên khi không phải làm việc với backend nữa.

 

2. Cấu hình FastCGI Cache (Dynamic Cache)

Tiếp theo mình sẽ đi vào chi tiết cấu hình FastCGI để cache nội dung động (PHP Scripts).

Mô hình Webserver trong bài này sẽ bao gồm các thành phần chính Nginx + FastCGI Cache + PHP-FPM

Bạn mở file cấu hình nginx

vi /etc/nginx/nginx.conf

Thêm vào block http {…} hai dòng sau:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=supercache:10m max_size=1000m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Đây là hai dòng quan trọng khai báo cấu hình FastCGI Cache.

fastcgi_cache_path

Chỉ ra đường dẫn chứa cache file là /etc/nginx/cache với các giá trị kèm theo.

  • levels giá trị này là quy tắc đặt tên và phân cấp thư mục cache, bạn xem hình bên dưới để hiểu thêm với levels=1:2levels=2:4
Levels 1:2

levels=1:2

Levels 2:4

levels=2:4

  • keys_zone đặt tên cho cache zone là supercache có dung lượng là 10m, bạn chú ý một chút về đơn vị dung lượng k/K là Kilobytes, m/M là Megabytes
  • max_size kích thước tối đa của toàn bộ cache là 1000m
  • inactive nếu một response không được sử dụng trong thời gian 60 phút thì nó sẽ bị xóa khỏi thư mục chứa cache.

fastcgi_cache_key

Định dạng Key (khóa) của cache file theo $scheme$request_method$host$request_uri có tác dụng để phân biệt các cache file với nhau. Nếu mở cache file bất kỳ bạn sẽ thấy định dạng của nó như bên dưới.

KEY: httpGETwww.thuysys.com/domain-hosting/wordpress-co-ban/tim-hieu-chmod-chown-cach-sua-loi-phan-quyen-wordpress-tren-linux.html
  • $scheme http
  • $request_method  GET
  • $host www.thuysys.com
  • $request_uri /domain-hosting/wordpress-co-ban/tim-hieu-chmod-chown-cach-sua-loi-phan-quyen-wordpress-tren-linux.html

Bạn có thể thay đổi định dạng Key bằng cách thêm bớt các biến sao cho đúng ý mình là được.

Đấy là ý nghĩa các thông số cấu hình FastCGI Cache cho nginx. Giờ bạn để ý cho mình keys_zonemax_size tại sao lại có giá trị lần lượt là 10m và 1000m, như vậy thừa chăng, chúng có ý nghĩa gì ?

Cache File

Hình bên trên là nội dung của một cache file thông thường, chỗ màu đỏ chính là Cache Keys, khi được Hash Key thành chuỗi mã hóa nó sẽ được lưu trên RAM.

Theo tài liệu nginx cung cấp thì 1m RAM có thể lưu trữ khoảng 8000 key với keys_zone 10m bạn sẽ lưu được 80.000 key tương đương với 80.000 cache files trong file system. Từ đây bạn có thể tính được dung lượng của keys_zone dựa vào số lượng cache file sinh ra cho site của mình. Với các web vài nghìn truy câp/ngày thì cũng còn khướt mới đạt tới còn số 80.000, thứ nữa cache file còn bị xóa bởi inactive=60m nữa nên bạn không cần để cao làm gì cho tốn bộ nhớ.

Riêng max_size là tổng dùng lượng cache file lưu trên ổ cứng. Bạn áng chừng con số phù hợp là được, vài GB đĩa cứng có nhằm nhò gì!

 

Một chú ý nữa, keys_zone có thể được dùng chung cho nhiều virtual host tương đương với nhiều website hoặc tách biệt ra không vấn đề gì cả.

Sang bước cấu hình tiếp theo, bạn thêm vào block server {…} nội dung sau.

Server {

# Không lưu cache khi truy cập khu vực quản trị wordpress.
 set $no_cache 0;

if ($request_uri ~* "/(wp-admin/)")
 {
 set $no_cache 1;
 }
 # Cấu hình FastCGI Cache cho PHP Scripts
 location ~ .php$ {
 try_files $uri =404;
 fastcgi_cache supercache;
 fastcgi_cache_valid 200 60m; # Chỉ cache lại các response có code là 200 OK trong 60 phút
 fastcgi_cache_methods GET HEAD; # Áp dụng với các phương thức GET HEAD
 add_header X-Fastcgi-Cache $upstream_cache_status; # Thêm vào header trạng thái cache MISS (chưa cache), HIT (đã cache)
 fastcgi_cache_bypass $no_cache; # no_cache=1 không lấy dữ liệu từ cache với request_uri bắt đầu bằng wp-admin.
 fastcgi_no_cache $no_cache; # Khi no_cache=1 đồng thời cũng không lưu cache với response trả về.

# Kết nối fastcgi_pass với php-fpm
 fastcgi_pass unix:/var/run/php-fpm/php5-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 include fastcgi_params;
 }

}

Cấu hình xong, khởi động lại webserver systemctl restart nginx rồi dùng trinh duyệt để xem kết quả, tốc độ lướt web sẽ làm bạn ngạc nhiêu đấy.

3. Cấu hình lưu Cache trên RAM

Tiếp theo chúng ta sẽ cấu hình mount File System (thư mục chứa cache file) lên RAM, đây là cách tạo RAM Disk trên linux rất hay, bạn nào dùng VPS có RAM nhiều một chút có thể thử cách này.

Nếu cài nginx trên Ubuntu hay CentOS mở file vi /etc/fstab ra thêm vào dòng sau:

tmpfs /etc/nginx/cache tmpfs defaults,size=100M 0 0

Bạn nào không rõ về cách mount trên linux và fstab là gì thì search google đọc thêm, bạn cần lưu ý giá trị size=100M nó có nghĩa thư mục mount sẽ chiếm tối đa 100M trên RAM, bộ nhớ ít thì để như vậy thôi.

Ấn :wq để lưu file, chạy thêm lệnh mount -a để tự mount.

Để kiểm tra lại kết quả bạn gõ lệnh df -af | grep tmpfs như hình bên dưới là ok.

Kiểm tra RAM Disk

4. Cấu hình Browser Cache (static cache)

Muốn cấu hình Web Browser cache nội dung tĩnh bạn thêm tiếp block location con nữa vào trong block server {…} với nội dung:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|wmv|3gp|avi|mpg|mpeg|mp4|flv|mp3|mid|wml|swf|pdf|doc|docx|ppt|pptx|zip)$ {
expires 365d;
access_log off;
}

Block location quy định những loại file nào được lưu cache trên trình duyệt và thời gian lưu cache là 365d (ngày) nếu thường xuyên update chỉnh sửa những file này bạn giảm thời gian expires xuống cho phù hợp. Bạn có thể chia ra, file hình ảnh video thời gian expires là 1M (1 tháng) với các file js, css ít thay đổi hơn thì để 1y (1 năm).

Directive access_log off quy định sẽ không ghi log truy cập đến các nội dung này giúp CPU đỡ bận rộn hơn.

Khi cấu hình cache cho trình duyệt, bạn chỉ thật sự cảm thấy hiệu quả khi lần thứ 2 truy cập trang web vì khi đó các file hình ảnh, scripts đã được lưu trên webbrowser của bạn tốc độ tải web tăng lên đáng kể.

Bạn tham khảo thêm một số giá trị thời gian khác để sử dụng cho linh hoạt:

  • ms: milliseconds
  • s: seconds
  • m: minutes
  • h: hours
  • d: days
  • w: weeks
  • M: months (30 days)
  • y: years (365 days)

Nếu muốn lưu 2 năm 6 tháng bạn nhập vào expires 2y6M cho bá đạo ^^

5. Bật nén Gzip Compression

Mục đích enable gzip cho website để giảm dung lượng dữ liệu trước khi truyền nội dung trên internet nhằm tiết kiệm băng thông (bandwidth), cũng là cách tăng tốc web hiệu quả.

Thêm đoạn code sau vào block server{…}

gzip on;
gzip_static on;
gzip_buffers 4 8k;
gzip_min_length 1100;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/css application/javascript text/xml application/xml+rss;

Toàn bộ chỉ thị trên đều có trong module ngx_http_gzip_module được mặc định trên nginx.

Chỉ có chỉ thị gzip_static là trong module ngx_http_gzip_static_module dùng để gửi file .gz đến client. Tuy nhiên không phải là module được biên dịch sẵn phải kiểm tra lại trước khi dùng chỉ thị này bằng lệnh nginx -V. Mình dùng nginx bản 1.9, 1.10, 1.11 thì thấy module này được biên dịch sẵn rồi, bạn nào bị lỗi bật nén gzip nginx thì chú ý chỗ này.

  • gzip : giá trị on đơn giản chỉ là enable tính năng gzip trên server.
  • gzip_static : giá trị on chỗ này có nghĩa sẽ kiểm tra file .gz có tồn tài trên server hay không.
  • gzip_buffers : thiết lập kích thước bộ nhớ đệm trên memory page tương đương 4 x 8k = 32k, theo một số lời khuyên 4 8k là phù hợp.
  • gzip_min_length: chỉ áp dụng gzip với các file có dung lượng từ 1100 byte trở lên.
  • gzip_vary: giá trị on để chèn thêm Vary: Accept-Encoding vào response header khi gzip, gzip_static đang được kích hoạt.
  • gzip_disable : chỉ thị này để vô hiệu hóa gzip trên trình duyệt IE6 “MSIE [1-6]\.” dựa vào User-Agent. Trình duyệt IE6 quá cũ rồi gzip không hoạt động được, bạn có thể thêm dòng gzip_disable “Mozilla / 4”; với trình duyệt cũ của Mozilla.
  • gzip_types : mặc định chỉ có text/plain được nén bạn phải bổ sung thêm các tập tin văn bản xml, css, js. Mình khuyên bạn dùng với những định dạng bên trên thôi kẻo lại có tác dụng ngược.

Trên đây là những chia sẻ về Caching trên NGINX và vài cách cấu hình cache cơ bản nhằm tăng tốc độ website một cách nhanh chóng mà hưu hiệu.

nguồn: thuysys