Cách tạo Cache, NGINX Caching, Reverse Proxy with Caching

Mô hình nginx caching

Xin chào anh em!
Lời đầu tiên xin được gửi tới anh em lời chúc sức khỏe và thành công trong cuộc sống!

Hôm nay xin được phép thảo luận và chia sẻ cùng anh em cách tạo cache cho website. Anh em nào biết rồi thì hãy cứ đọc nhé, mình tin nó không thừa đâu hoặc có thể giúp ích thêm cho anh em.

Trước hết, câu hỏi đặt ra là việc tạo cache cho website để làm gì?
Xin được trả lời đơn giản nhất như sau:

Hầu hết các web server có thể xử lý các lượng truy cập bình thường và đa phần các trang web không có quá nhiều truy cập. Vì vậy, có thể bạn tự hỏi: Tại sao bạn nên cache trang web của bạn được hỗ trợ PHP? Các máy chủ web có thể phục vụ nhiều yêu cầu (request), nhiều file cùng một lúc, nhưng tất cả các file này nên là file tĩnh. Một tập lệnh PHP được thực thi bởi máy chủ web và tiếp theo nó sẽ tạo ra dữ liệu HTML được gửi đến người dùng (trình duyệt web). Cho nên khi thực hiện điều này, máy chủ cần sử dụng nhiều bộ nhớ hơn cách gửi một file tới người dùng. Ta cần cache lại thì tốt và nhanh hơn.

Đối với các website sử dụng mã nguồn wordpress bạn có thể sử dụng cách plugin tạo cache như:
– WP Super Cache
– WP rocket

Còn nếu không dùng mã nguồn wordpress thì việc tạo cache cũng tương đối đơn giản phải không nào. (Anh em cần hỏi chỗ này thì để lại bình luận nhé)

Nhưng trong bài này, mình xin chia sẻ một số phương pháp tăng tốc web trên NGINX, mình đã làm với VPS (máy chủ) của mình, để xem tại sao thiên hạ lại gọi nginx là Caching King.

Để giải thích chi tiết thì tương đối dài, và sẽ khá rối rắm.
Mình sẽ giải thích nhanh bằng hình ảnh mô hình đơn giản như sau.

Mô hình nginx caching

Mô hình nginx caching

Với 3 mô hình trên, mình đánh số thứ tự khoanh tròn màu đỏ. Chỉ cần cấu hình file nginx của domain là xong thôi, rất đơn giản mà không phải thay đổi gì liên quan đến source code web của bạn.
Sau đây là các bước triển khai:

Mô hình 1:
Cấu hình trên mình dùng cho wordpress luôn, các mã nguồn khác tương tự vậy.
Các hướng dẫn cấu hình nginx với chức năng Web Proxy – FastCGI Cache – Browser Cache – Cách bật nén Gzip trên server sao cho đạt hiệu suất cao nhất.

fastcgi_cache_path /home/domain.com/cache levels=1:2 keys_zone=domaincache_cache:2000m max_size=1000m inactive=2d;
fastcgi_cache_key “$scheme$request_method$host$request_uri”;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
server {
listen 443 ssl;
server_name www.domain.com;

# SSL
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

rewrite ^(.*) https://domain.com$1 permanent;
}
server {
listen 80;
server_name domain.com www.domain.com;
rewrite ^(.*) https://domain.com$1 permanent;
}

server {
listen 443 ssl;

# access_log off;
#access_log /home/domain.com/logs/access.log;
# error_log off;
#error_log /home/domain.com/logs/error.log;

root /home/domain.com/public_html;
index index.php index.html index.htm;
server_name domain.com;

# SSL
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

# Improve HTTPS performance with session resumption
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;

# DH parameters
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# Enable HSTS
add_header Strict-Transport-Security “max-age=31536000” always;

location / {
try_files $uri $uri/ /index.php?$args;
}

set $skip_cache 0;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != “”) {
set $skip_cache 1;
}
if ($request_uri = “/”) {
set $skip_cache 1; #không cache trang chủ.
}
# Don’t cache uris containing the following segments
if ($request_uri ~* “/wp-admin/|/admin|/xmlrpc.php|wp-.*.php|/feed/|index.php|.php|.xml|sitemap(_index)?.xml”) {
set $skip_cache 1;
}

# Don’t use the cache for logged in users or recent commenters
if ($http_cookie ~* “comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in”) {
set $skip_cache 1;
}

# Custom configuration
include /home/domain.com/public_html/*.conf;

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_connect_timeout 1000;
fastcgi_send_timeout 1000;
fastcgi_read_timeout 1000;
fastcgi_buffer_size 256k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
fastcgi_param SCRIPT_FILENAME /home/domain.com/public_html$fastcgi_script_name;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache domaincache_cache;
fastcgi_cache_valid 200 2d;
fastcgi_cache_methods GET HEAD;
add_header X-Fastcgi-Cache $upstream_cache_status;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
location /php_status {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/domain.com/public_html$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
allow 127.0.0.1;
deny all;
}
# Disable .htaccess and other hidden files
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* \.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso|eot|svg|ttf|woff)$ {
gzip_static off;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;
access_log off;
expires 30d;
break;
}

gzip_static off;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;
access_log off;
expires 365d;
break;
}

location ~* \.(txt|js|css)$ {
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;
access_log off;
expires 365d;
break;
}
}

Giải thích:
Đây là dòng quan trọng khai báo cấu hình FastCGI Cache.
– fastcgi_cache_path /home/domain.com/cache levels=1:2 (thư mục tạo cache của bạn và giá trị này là quy tắc đặt tên và phân cấp thư mục cache)
– keys_zone=domaincache_cache:2000m : đặt tên cho cache zone là domaincache_cache có dung lượng là 2000m, bạn chú ý một chút về đơn vị dung lượng k/K là Kilobytes, m/M là Megabytes
– max_size=1000m inactive=2d; (kích thước tối đa của toàn bộ cache và nếu một response không được sử dụng trong thời gian 2 ngày thì nó sẽ bị xóa khỏi thư mục chứa cache.

Sau khi khởi động lại nginx.
Ta bắt đầu kiểm tra xem đã cache chưa.

curl -I https://domain.com/abc/

Kết quả sau khi cache

Kết quả sau khi cache

Lần đầu tiên truy cập sẽ cho ta thông báo cache là Miss, hãy thử lại lần nữa, nếu báo Hit là thành công.

Như vậy là chúng ta đã tạo cache xong, nhưng chúng ta cần lưu thư mục cache vào Ram thì tốc độ sẽ tốt hơn.
Vì tốc độ đọc trên Ram luôn cao hơn trên ổ cứng.
Trên SSH:
# nano /etc/fstab
tmpfs /home/domain.com/cache tmpfs defaults,size=1000M 0 0
# mount -a
Để kiểm tra lại kết quả bạn gõ lệnh:
df -ah | grep tmpfs
Thấy thư mục /home/domain.com/cache là ok

Mô hình 2:

Việc thực hiện cache ngay trên con reproxy sẽ giảm thiểu kết nối đến vps (máy chủ chính), tốc độ gần như tức thời.
Trên con reproxy sửa cấu hình nginx như sau:

proxy_cache_path /home/domain.com/cache levels=1:2 keys_zone=domaincache:100m max_size=1000m
inactive=1d use_temp_path=off;r_name domain.com www.domain.c
server {
listen 80;
server_name domain.com www.domain.com;
return 301 https://domain.com$request_uri;

}

server {

listen 443 ssl;
server_name www.domain.com domain.com;

# SSL
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

# Improve HTTPS performance with session resumption
#ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;

# DH parameters
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# Enable HSTS
add_header Strict-Transport-Security “max-age=31536000” always;

# access_log /home/domain.com/logs/access.log;
# error_log /home/domain.com/logs/error.log;

location / {
proxy_cache domaincache;
proxy_cache_revalidate on;
proxy_cache_min_uses 1;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_valid 301 1h;
# proxy_cache_valid 404 1s;
proxy_cache_methods GET HEAD;
proxy_cache_valid 200 1d;
proxy_cache_background_update on;
proxy_cache_lock on;

if ($request_uri = “/”) { set $no_cache 1; }
if ($request_uri ~* “.php”) { set $no_cache 1; }
if ($request_uri ~* “.txt”) { set $no_cache 1; }
if ($request_uri ~* “.js”) { set $no_cache 1; }
if ($request_uri ~* “fbclid”) { set $no_cache 1; }
if ($request_uri ~* “search_gcse”) { set $no_cache 1; }
if ($request_method = POST) {
set $no_cache 1;
}

# Don’t cache url’s containing the following segments
if ($request_uri ~* “/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml”) {
set $no_cache 1;
}
# Don’t use the cache for logged in users or recent commenters
if ($http_cookie ~* “comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in”) {
set $no_cache 1;
}

proxy_cache_bypass $cookie_nocache $arg_nocache $no_cache;

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_set_header X-Forwarded-Proto $scheme;

add_header X-Cache-Status $upstream_cache_status;

proxy_pass http://ip-vps-chinh;
proxy_read_timeout 90;

proxy_redirect http://ip-vps-chinh https://domain.com;
}
}

Muốn cache vào ram thì làm tương tự bên trên.

Mô hình 3:

Nó là tổng hợp của hai mô hình 1 và 2, nhưng mình thấy nó không cần thiết.

Như vậy là mình đã trình bày xong phương pháp tăng tốc web trên NGINX. Mình đã cố trình bày rõ, nhưng sẽ khó có thể thoát hết các nội dung.

Hy vọng anh em cùng thảo luận để bài viết của em lên top google search. Hihi.
Cảm ơn anh em đã đọc topic của mình.

ps: Hy vọng bài viết của em vào nhóm bài viết chất lượng. Ai đọc mà ko like, e cắt trym. Hehe

Update: Nên kết hợp đồng thời với việc tạo cache thông thường trên ổ cứng để cho hiệu suất tốt nhất.

Nguồn: https://cafemmo.club/threads/thao-luan-va-chia-se-cach-tao-cache-nginx-caching-reverse-proxy-with-caching.2400/

A Guide to Caching with NGINX and NGINX Plus

Trả lời

Email của bạn sẽ không được hiển thị công khai.

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.