Khắc phục lỗi Nginx Cache MISS liên tục: Header Set-Cookie và Authorization

trung bình Nginx2026-06-13| Nginx trên Linux (Ubuntu, CentOS, Debian) đóng vai trò Reverse Proxy cho các backend như Node.js, PHP-FPM hoặc Python.

Error Message

X-Cache-Status: MISS (Cache remains empty despite correct proxy_cache_path configuration)
#nginx#proxy_cache#devops#web-performance#sysadmin

Vấn đề "Luôn MISS" gây ức chế

Bạn đã dành thời gian cấu hình proxy_cache_path và ánh xạ các zone của mình. Bạn chạy lệnh curl, mong đợi phản hồi cực nhanh trong 5ms, nhưng các header vẫn ngoan cố hiển thị MISS. Ngay cả sau khi tải lại mười lần, thư mục cache trên đĩa của bạn vẫn trống rỗng và TTFB (Time to First Byte) của backend vẫn chậm chạp ở mức 200ms hoặc cao hơn.

X-Cache-Status: MISS

Điều này xảy ra vì Nginx được thiết kế để "an toàn" theo mặc định. Nó thà làm chậm trang web của bạn còn hơn là vô tình cung cấp dữ liệu phiên riêng tư của người dùng này cho khách truy cập khác.

Nguyên nhân gốc rễ: Nginx đang quá thận trọng

Nginx tuân thủ nghiêm ngặt các tiêu chuẩn HTTP caching. Nếu backend của bạn (Node.js, Laravel, Django, v.v.) gửi các header ám chỉ một phiên duy nhất, Nginx sẽ từ chối lưu trữ phản hồi. Ba thủ phạm phổ biến nhất là:

  • Set-Cookie: Nếu ứng dụng của bạn gửi PHPSESSID hoặc connect.sid, Nginx giả định trang đó đã được cá nhân hóa.
  • Authorization: Nếu yêu cầu bao gồm Bearer token hoặc Basic Auth, Nginx coi phản hồi đó là riêng tư.
  • Cache-Control: Các header như no-cache, no-store, hoặc private yêu cầu Nginx một cách rõ ràng là không được can thiệp.

Khi Nginx thấy những header này, nó mặc định chuyển sang MISS để ngăn rò rỉ dữ liệu nhạy cảm. Để khắc phục, bạn phải chỉ định rõ ràng cho Nginx biết những header nào cần bỏ qua.

Cách khắc phục: Ghi đè logic Header mặc định

Chỉ thị proxy_ignore_headers là công cụ chính của bạn ở đây. Nó yêu cầu Nginx bỏ qua các hướng dẫn cụ thể từ backend và vẫn tiến hành lưu cache nội dung.

Bước 1: Cập nhật cấu hình Nginx của bạn

Mở cấu hình trang web của bạn (thường ở /etc/nginx/sites-available/) và sửa đổi block location. Thêm các dòng này sẽ buộc Nginx lưu cache ngay cả khi có cookie:

location / {
    proxy_pass http://backend_upstream;
    proxy_cache my_cache_zone;
    
    # Yêu cầu Nginx bỏ qua các header này từ backend
    proxy_ignore_headers Set-Cookie Cache-Control Expires;
    
    # Ẩn header Set-Cookie khỏi người dùng cuối để ngăn rò rỉ phiên (session bleeding)
    proxy_hide_header Set-Cookie;

    # Lưu cache các phản hồi 200 thành công trong 60 phút
    proxy_cache_valid 200 60m;

    # Header để gỡ lỗi
    add_header X-Cache-Status $upstream_cache_status;
}

Bước 2: Xử lý các yêu cầu có xác thực

Nếu API của bạn sử dụng header Authorization nhưng cung cấp cùng một dữ liệu cho mọi người (như danh sách sản phẩm công khai), Nginx vẫn sẽ bỏ qua cache. Để vượt qua điều này, hãy bật proxy_cache_allow_authentication:

location /api/public {
    proxy_cache my_cache_zone;
    proxy_cache_allow_authentication on;
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid 200 10m;
}

Bước 3: Kiểm tra và Tải lại

Trước khi áp dụng các thay đổi, hãy xác minh cú pháp của bạn. Một dấu chấm phẩy bị thiếu cũng có thể làm hỏng máy chủ web.

sudo nginx -t
sudo systemctl reload nginx

Xác minh: Xác nhận trạng thái HIT

Sử dụng curl để kiểm tra các header. Yêu cầu đầu tiên có khả năng sẽ là MISS khi Nginx lấy dữ liệu và ghi vào đĩa. Yêu cầu thứ hai sẽ là HIT.

curl -I https://yourdomain.com/api/data

Tìm các dòng cụ thể sau:

HTTP/1.1 200 OK
... 
X-Cache-Status: HIT
...

Nếu bạn vẫn thấy MISS, hãy đảm bảo thư mục proxy_cache_path của bạn có quyền ghi cho người dùng www-data hoặc nginx. Bạn có thể kiểm tra việc này bằng lệnh ls -ld /var/cache/nginx.

An toàn là trên hết: Các thực hành tốt nhất

Buộc lưu cache là một kỹ thuật mạnh mẽ nhưng đi kèm rủi ro. Hãy tuân thủ các quy tắc sau để tránh cung cấp dữ liệu riêng tư cho nhầm người:

  • Cô lập các đường dẫn nhạy cảm: Không bao giờ sử dụng proxy_ignore_headers Set-Cookie trên các trang /admin, /checkout, hoặc /settings.
  • Sử dụng Cache Bypassing: Triển khai proxy_cache_bypass $cookie_nocache. Điều này cho phép bạn cung cấp nội dung đã lưu cache cho khách trong khi vẫn cung cấp dữ liệu mới, được cá nhân hóa cho người dùng đã đăng nhập.
  • Loại bỏ Cookie: Luôn sử dụng proxy_hide_header Set-Cookie khi bỏ qua cookie để đảm bảo trình duyệt không lưu trữ ID phiên cũ từ cache.

Related Error Notes