Hotline : 1800 1093 - 07 088 44444
Thích
Chia sẻ

Hướng dẫn cấu hình NGINX cache nhanh chóng

24/03/2021

Chúng ta đều biết, hiệu năng của ứng dụng và website là yếu tố quan trọng quyết định thành công của một doanh nghiệp. Tuy nhiên, quá trình làm cho ứng dụng hoặc website hoạt động tốt hơn thường không rõ ràng. Chất lượng code và cơ sở hạ tầng tất nhiên là quan trọng. Nhưng trong nhiều trường hợp, bạn có thể cải thiện trải nghiệm của người dùng một cách rõ rệt bằng cách triển khai và tối ưu hóa caching trong application stack. Bài viết hôm nay sẽ chia sẻ các kỹ thuật từ căn bản đến nâng cao giúp tận dụng tối đa sức mạnh của tính năng cache mà NGINX hỗ trợ để nâng cao hiệu suất. Hãy cùng tìm hiểu cách cấu hình cache NGINX của Vietnix ngay sau đây!

Tổng quan về NGINX cache

Một hệ thống cache nội dung (content cache) nằm giữa người dùng (client) và server (origin server), và lưu trữ lại mọi nội dung nó nhìn thấy. Nếu một client requests content đã được lưu trữ trong cache, nó sẽ return cho người dùng trực tiếp mà không cần phải liên hệ với origin server để lấy nội dung. Điều này giúp nâng cao hiệu suất vì server cache nằm gần người dùng hơn, và sử dụng application server hiệu quả hơn bởi vì nó không cần phải xử lý để tạo ra kết quả trả lời cho mỗi lần user request.

Có nhiều vị trí tiềm năng để cache giữa web browser và server chạy ứng dụng: cache ở browser của client, các lớp cache trung gian, CDN, hệ thống load balancer và reverse proxy nằm phía trước server ứng dụng. Caching, thậm chí khi chỉ được đặt ở load balancer hoặc reverse proxy level cũng giúp tăng hiệu năng rất lớn.

Một ví dụ, năm ngoái khi tôi nhận nhiệm vụ tối ưu hóa tốc độ cho một website đang bị load chậm. Một trong những thứ đầu tiên tôi chú ý là nó mất hơn 1 giây để load trang home page. Sau khi debug, tôi phát hiện ra lý do là gì page bị đánh dấu là not cachable (không được phép cache), website được generate dynamically mỗi khi có request. Bản thân home page nó không được thay đổi content thường xuyên và cũng không được cá nhân hóa (personalized), nên việc phải generate lại nội dung mỗi khi có truy cập là điều không cần thiết. Dựa theo kinh nghiệm, tôi cấu hình để cache home page 5s trên load balancer, và chỉ với việc này, hiệu suất được cải thiện một cách đáng kinh ngạc. Time to first by (TTFB) hạ xuống chỉ còn vài miliseconds và page load nhanh hơn thấy rõ.

Cấu hình cache NGINX
Cấu hình cache NGINX

NGINX thường được triển khai như một reverse proxy hoặc một load balancer trong một application stack và được trang bị đầy đủ các tính năng cache. Phần tiếp theo, chúng ta sẽ cùng xem cách để cấu hình caching căn bản với NGINX

Cách cài đặt và cấu hình cache NGINX cơ bản

Chỉ có 2 directive cần sử dụng để enable basic caching: proxy_cache_pathproxy_cache.

  • proxy_cache_path directive thiết lập đường dẫn (path) và cấu hình (configuration) của cache.
  • proxy_cache directive kích hoạt cache.
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
    # ...
    location / {
        proxy_cache my_cache;
        proxy_pass http://my_upstream;
    }
}

Các tham số cấu hình của proxy_cache_path directive bao gồm:

  • Đường dẫn trên local disk đến vị trí lưu file cache được gọi là /path/to/cache
  • levels: Thiết lập một cấu trúc thư mục hai cấp (two-level) trong /path/to/cache. Nếu có một số lượng lớn file ở trong 1 thư mục thì việc truy cập vào thư mục sẽ bị chậm. Do đó, NGINX khuyến nghị nên sử dụng cấu trúc thư mục two-level khi sử dụng cache. Nếu tham số levels không được cấu hình, NGINX sẽ đặt tất cả file cache vào cùng 1 thư mục.
  • keys_zone thiết lập một vùng shared memory để lưu trữ cache keys và metadata như là usage timers. Duy trì một bản copy của keys trong bộ nhớ cho phép NGINX nhanh chóng xác định một request là HIT hay là MISS mà không cần phải kiểm tra dữ liệu trên ổ cứng, điều này giúp tăng tốc độ kiểm tra đáng kể. Zone với dung lượng 1MB có thể chứa khoảng 8000 key, zone với dung lượng 10MB như trong ví dụ có thể chứa khoảng 80,000 keys.
  • max_size thiết lập chặn trên (upper limit) của cache size (10GB trong ví dụ phía trên). Tham số này không bắt buộc (optional), nếu không được khai báo đồng nghĩa với việc cho phép cache sử dụng toàn bộ dung lượng ổ cứng còn trống. Khi cache size đạt đến limit, một process có tên gọi cache manager sẽ xóa những file ít được sử dụng nhất để giữ cho cache size trở lại thấp hơn limit.
  • inactive chỉ định thời gian tối đa một item có thể tồn tại trong cache mà không được sử dụng. Trong ví dụ, nếu một file không được request trong vòng 60 phút sẽ tự động bị xóa bởi process cache manager, không cần quan tâm nó đã hết hạn hay chưa. Giá trị mặc định là 10 phút (10m). Inactive content khác với expired content. NGINX không tự động xóa content đã hết hạn (expired) như nó được khai báo bởi cache control header (ví dụ: Cache-Control: max-age=120). Expired (stale) content được xóa chỉ khi nó không được sử dụng trong khoảng thời gian được chỉ định bởi inactive. Khi expired content được truy cập, NGINX sẽ refresh nó từ origin server và reset inactive timer.
  • NGINX sẽ ghi những file được chỉ định cho cache vào trong một khu vực lưu trữ tạm (temporary storage) trước, và sử dụng directive use_temp_path=off sẽ chỉ định NGINX write cache trực tiếp vào thư mục chứa cache mà không cần lưu vào file tạm. Khuyến nghị nên cấu hình tham số này bằng off để tránh thao tác copy data không cần thiết giữ file system. use_temp_path được giới thiệu ở NGINX version 1.7.10.

Và cuối cùng proxy_cache directive kích hoạt cache tất cả content match URL của block location chứa nó (trong ví dụ là là location /). Bạn cũng có thể sử dụng proxy_cache directive ở server block, it sẽ apply cache chung cho tất cả location block trong server nếu location đó không có proxy_cache directive của riêng nó.

Phục vụ cached content khi Origin server bị Down

Một tính năng của NGINX content caching là NGINX có thể được cấu hình để phục vụ các content đã hết hạn (stale content) trong cache của nó khi nó không thể lấy được content mới từ origin server. Trường hợp này xảy ra khi tất cả origin server của cached resources bị down hoặc không đang quá tải. Thay vì trả về error code cho client, NGINX sẽ phục vụ nội dung cũ đang có trong cache cho client. Điều này cung cấp thêm 1 level chịu lỗi cho server chạy ứng dụng mà NGINX đang làm proxy cho nó, giúp nâng cao uptime trong trường hợp server bị lỗi hoặc traffic tăng cao đột biến. Để kích hoạt tính năng này, sử dụng proxy_cache_use_stale directive:

location / {
    # ...
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
}

Với cấu hình trên, nếu NGINX nhận phải lỗi error, timeout, hoặc bất kỹ lỗi 5xx nào được liệt kê phía trên từ origin server và nó có stale version của URL được request trong cache, nó sẽ dùng nội dung của stale file (cache cũ) trả về cho client thay vì trả về lỗi.

Tối ưu cache và cải thiện hiệu suất 

NGINX có rất nhiều options giúp fine-tuning hiệu suất của cache. Dưới đây là một vài ví dụ:

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    # ...

    location / {
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_pass http://my_upstream;
    }
}

Những directive trên có tác dụng:

  • proxy_cache_revalidate ra lệnh cho NGINX sử dụng thêm GET requests khi làm mới (refreshing) content từ phía origin server. Nếu một client request một item đã được cache nhưng expired bởi cache control header, NGINX đính kèm If-Modified-Since vào header của GET request mà nó gửi đến origin server. Điều này giúp tiết kiệm băng thông, bởi vì server chỉ gửi lại full nội dung của item chỉ khi nội dung đó đã bị thay đổi kể từ thời điểm được ghi nhận trong header Last-Modified trong file cache đang được lưu.
  • proxy_cache_min_uses thiết lập số lần mà item phải được request bởi client trước khi NGINX quyết định cache lại chúng. Điều này sẽ rất có ích khi mà hệ thống cache thường hay bị đầy, vì nó giúp đảm bảo chỉ có những items thường được truy cập mới được add vào cache. Mặc định, proxy_cache_min_use có gía trị là 1.
  • Tham số updating của proxy_cache_use_stale directive, kết hợp với việc kích hoạt proxy_cache_background_update directive, cho phép NGINX sử dụng stale content để phục vụ cho client khi một item expired hoặc nó đang trong quá trình được update nội dung mới từ origin server. Tất cả việc cập nhật sẽ được thực hiện ở background. Stale file sẽ được sử dụng cho đến khi quá trình update hoàn tất và file cache được download hoàn chỉnh.
  • Với proxy_cache_lock được enable, nếu nhiều client cùng request một file mà file đó đang không có trong cache (MISS), chỉ có request đầu tiên trong số những request đó được phép đẩy về origin server. Những request còn lại sẽ phải chờ cho đến khi request đầu tiên hoàn tất và dữ liệu được lưu vào cache, và chúng sẽ sử dụng dữ liệu từ file cache này. Nếu không có proxy_cache_lock được bật, tất cả request bị cache miss sẽ đi thẳng về origin server.

Theo dõi trạng thái cache

Ta có thể theo dõi trạng thái cache của một request bằng cách sử dụng add_header directive:

add_header X-Cache-Status $upstream_cache_status;

Ví dụ trên add một HTTP header có tên X-Cache-Status vào response của client cho phép client theo dõi được trạng thái cache của request. Những giá trị có thể có của $uptream_cache_status:

  • MISS – dữ liệu cần phản hồi không có trong cache và nó được fetch từ origin server. Dữ liệu phản hồi có thể sẽ được cache lại.
  • BYPASS – phản hồi được fetch từ origin server thay vì được phục vụ từ cache bởi vì request match proxy_cache_bypass directive. Phản hồi sau đó có thể sẽ được cache lại.
  • EXPIRED – entry trong cache đã expired. Dữ liệu phản hồi được fetch từ origin server.
  • STALE – dữ liệu nhận dược là dữ liệu cũ vì origin server không phản hồi chính xác hoặc proxy_cache_use_stale được cấu hình.
  • UPDATING – Nội dung đã cũ vì cache entry hiện đang được update trong response của request trước đó, và proxy_cache_use_stale updating được cấu hình.
  • REVALIDATEDproxy_cache_revalidate directive được kích hoạt và NGINX xác nhận content đang được cache hiện tại vẫn còn hợp lệ (If-Modified-Since hoặc If-None-Match).
  • HIT – dữ liệu phản hồi hoàn toàn hợp lệ và được phục vụ từ cache.

NGINX quyết định cache hoặc không cache như thế nào ?

Mặc định, NGINX tuân thủ theo header Cache-Control của origin servers. Nó không cache response mà có Cache-Control set thành Private, No-Cache, hoặc No-Store hoặc với Set-Cookie trong response header. NGINX chỉ cache GET hoặc HEAD requests. NGINX cũng không cache response nếu proxy_buffering được set thành off. Giá trị này mặc định là on.

Có thể bỏ qua Cache-Control header hay không?

Có, sử dụng proxy_ignore_headers directive. Ví dụ, với cấu hình như sau:

location /images/ {
    proxy_cache my_cache;
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid any 30m;
    # ...
}

NGINX sẽ bỏ qua Cache-Control header cho mọi thứ nằm trong /images/. proxy_cache_valid directive thiết lập thời gian hết hạn (expiration) của dữ liệu được cache và nó cần phải được cấu hình nếu chúng ta bỏ qua (ignore) Cache-Control header. NGINX sẽ không cache file nếu không có thời gian hết hạn (expiration).

NGINX có thể cache content với Set-Cookie trong Header không?

Có, bằng cách sử dụng proxy_ignore_headers directive như đã được bàn phía trên.

NGINX có thể cache POST request được không?

Có, sử dụng proxy_cache_methods directive:

proxy_cache_methods GET HEAD POST;

Request có thể bỏ qua hệ thống cache được không?

Có, sử dụng proxy_cache_bypass directive:

location / {
    proxy_cache_bypass $cookie_nocache $arg_nocache;
    # ...
}

Directive trên khai báo những loại request mà NGINX sẽ request content trực tiếp từ origin server thay vì kiểm tra và tìm chúng trong hệ thống cache. Điều này còn thường được gọi là “đào lỗ” (punching a hole) xuyên qua hệ thống cache. Trong ví dụ này, NGINX thực hiện điều đó cho những request có nocache cookie hoặc argument, ví dụ: https://vietnix.vn/?nocache=true. NGINX có thể vấn sẽ cache kết quả response để phục vụ cho những request tiếp theo nếu chúng không bypass.

NGINX sử dụng cache key như thế nào?

Mặc định, NGINX sử dụng key có giá trị tương tự như kết quả hash MD5 của những biến NGINX sau: $scheme$proxy_host$request_uri

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    # ...

    location / {
        proxy_cache my_cache;
        proxy_pass http://my_upstream;
    }
}

Trong cấu hình trên, cache key cho https://vietnix.vn/firewall-anti-ddos/ được tính toán bằng hàm md5(“http://my_upstream:80/firewall-anti-ddos)

Lưu ý rằng biến $proxy_host được sử dụng để hash thay vì dùng hostname thực sự (vietnix.vn). $proxy_host được khai báo bằng tên và port của proxied server được chỉ định trong directive proxy_pass.

Để thay đổi những biến được sử dụng để làm key, sử dụng directive proxy_cache_key.

Có thể sử dụng Cookie thành một phần của cache key không?

Hoàn toàn có thể, cache key có thể được cấu hình bởi bất cứ giá trị nào, ví du:

proxy_cache_key $proxy_host$request_uri$cookie_jessionid;

Ví dụ trên sử dụng giá trị của cookie JSESSIONID thành một phần của cache key. Item của những request có cùng URI nhưng khác JSESSIONID được cache thành những item khác nhau.

Nếu bạn có thắc mắc hay có vấn đề cần hỗ trợ, bạn có thể liên hệ trực tiếp với Vietnix thông qua các kênh sau:
  • Hotline: 1800 1093 - 07 088 44444
  • Email: support@vietnix.vn
  • Hoặc chat trực tiếp với Vietnix thông qua biểu tượng Livechat ở góc phải màn hình. Đội ngũ chuyên viên của chúng tôi luôn sẵn sàng tư vấn và hỗ trợ bạn 24/7.
Vietnix hiện đang có chương trình khuyến mãi lớn nhất trong năm, giảm giá 50%  dịch vụ Hosting. Đăng ký dùng thử ngay và Vietnix sẽ hoàn tiền 100% nếu quý khách không hài lòng với chất lượng sản phẩm, dịch vụ!
Mình là Bo - admin của Quản Trị Linux. Mình đã có 10 năm làm việc trong mảng System, Network, Security và đã trải nghiệm qua các chứng chỉ như CCNP, CISSP, CISA, đặc biệt là chống tấn công DDoS. Gần đây mình trải nghiệm thêm Digital Marketing và đã hòan thành chứng chỉ CDMP của PersonVUE. Mình rất thích được chia sẻ và hỗ trợ cho mọi người, nhất là các bạn sinh viên. Hãy kết nối với mình nhé!
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
VNCoupon
VNCoupon
23 hours ago

Cám ơn tác giả, đây là bài viết chi tiết nhất về cache nginx mà mình đọc đc trên mạng! Chúc bạn sức khỏe để có thể viết thêm nhiều bài viết hay nữa.

Nguyễn Thanh Trường
Editor
Nguyễn Thanh Trường
4 hours ago
Reply to  VNCoupon

Vietnix cảm ơn bạn đã quan tâm tới bài viết này. Đội ngũ Vietnix sẽ cố gắng cung cấp thêm nhiều kiến thức tới bạn đọc hơn nữa!