Tối ưu hóa tốc độ cho WordPress: nginx + Varnish cache

Ở bài trước mình đã hướng dẫn các bạn Cài đặt nginx, PHP 5.3, MySQL (LEMP) trên CentOS 6.x để chạy WordPress. Còn hôm nay mình sẽ nói về một trong những cách tối ưu tốc độ cho WordPress, bằng việc cài đặt Varnish cache và cấu hình bổ sung giúp nginx hoạt động mượt mà hơn.

Bản thân nginx đã có tốc độ xử lý cao hơn nhiều so với Apache. Thêm sự hỗ trợ của Varnish cache nữa, mình chắc rằng tốc độ tải của website sẽ cải thiện một trông thấy. Thêm một lý do nữa, tốc độ tải của website là một trong những tiêu chí giúp SEO tốt hơn, vì thế đừng chần chừ khi bạn vẫn chưa cài Varnish cache cho server của mình.

Mình không muốn mất thời gian của các bạn để nói về Varnish cache (tại sao và như thế nào, blah blah…), những kiến thức chuyên sâu đó chỉ dành cho trình độ kỹ sư đọc và nghiên cứu. Mục đích của chúng ta là cài đặt và cấu hình nó sao cho tốc độ tải về của WordPress, cũng như website nói chung được cải thiện nhanh hơn.

Sơ đồ hoạt động của Varnish cache.

Sơ đồ hoạt động của Varnish cache.

Cũng như mọi khi, bài viết này mình thực hiện trên CentOS 6 64bit.

1. Cài đặt và cấu hình Varnish cache 3

1. Cài đặt Varnish cache

Cài đặt bằng lênh yum, nhưng trước tiên chúng ta cần cài Repo trước:

rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-3.0.el6.rpm
yum install varnish
chkconfig --level 345 varnish on

Tham khảo thêm: Cài đặt Varnish cache.

2. Cấu hình Varnish cache

Sửa file cấu hình của Varnish /etc/sysconfig/varnish. Tìm và đổi cổng dịch vụ của Varnish cache từ VARNISH_LISTEN_PORT=6081 thành VARNISH_LISTEN_PORT=80. Và thêm đoạn cấu hình sau vào cuối file:

#Cho phep Varnish dung 256MB RAM de luu cache
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

Sửa file VCL (Varnish Configuration Language) /etc/varnish/default.vcl thay thế toàn bộ bằng đoạn cấu hình sau. File này đã được tối ưu cho WordPress, bạn có thể dùng ngay mà không cần sửa gì. Link gốc trên GibHub.

backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

sub vcl_recv {

    # Allow the back-end to serve up stale content if it is responding slowly.
    set req.grace = 2m;

    # Always cache the following file types for all users.
    if ( req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$" ) {
        unset req.http.cookie;
    }
 
    # Don't serve cached pages to logged in users
    if ( req.http.cookie ~ "wordpress_logged_in" || req.url ~ "vaultpress=true" ) {
        return( pass );
    }
 
    # Drop any cookies sent to WordPress.
    if ( ! ( req.url ~ "wp-(login|admin)" ) ) {
        unset req.http.cookie;
    }

    # Handle compression correctly. Different browsers send different
    # "Accept-Encoding" headers, even though they mostly all support the same
    # compression mechanisms. By consolidating these compression headers into
    # a consistent format, we can reduce the size of the cache and get more hits.
    # @see: http://varnish.projects.linpro.no/wiki/FAQ/Compression
    if ( req.http.Accept-Encoding ) {
 
        if ( req.http.Accept-Encoding ~ "gzip" ) {
            # If the browser supports it, we'll use gzip.
            set req.http.Accept-Encoding = "gzip";
        }
 
        else if ( req.http.Accept-Encoding ~ "deflate" ) {
            # Next, try deflate if it is supported.
            set req.http.Accept-Encoding = "deflate";
        }
 
        else {
            # Unknown algorithm. Remove it and send unencoded.
            unset req.http.Accept-Encoding;
        }
 
    }
 
}
 
sub vcl_fetch {
 
    # Allow items to be stale if needed.
    set beresp.grace = 2m;
 
    # Drop any cookies WordPress tries to send back to the client.
    if ( ! req.url ~ "wp-(login|admin)" && ! req.http.cookie ~ "wordpress_logged_in" ) {
        unset beresp.http.set-cookie;
    }
 
}

Tham khảo cấu hình của mình: varnishdefault.vcl.

2. Cấu hình cho nginx

Bạn nên đọc bài viết trước mình nói về cách Cài đặt nginx, PHP 5.3, MySQL (LEMP) trên CentOS 6.x. Bởi vì mình sẽ cấu hình cho nginx hoạt động với Varnish cache dựa trên cấu hình cũ đó.

Mở file cấu hình virtual hosts của nginx:

vi /etc/nginx/conf.d/default.conf

đổi cổng dịch vụ của nginx từ listen 80 sang listen 8080.

Bật chế độ nén trang bằng Gzip cho nginx, sửa file cấu hình chính /etc/nginx/nginx.conf. Thêm vào trong http { }:

http {
    ...

    gzip              on;
    gzip_vary         on;
    gzip_http_version 1.1;
    gzip_comp_level   5;
    gzip_buffers      16 8k;
    gzip_min_length   1024;
    gzip_proxied      any;
    gzip_disable      "MSIE [1-6].(?!.*SV1)";
    gzip_types        text/plain
                      text/css
                      text/js
                      text/xml
                      text/javascript
                      application/javascript
                      application/x-javascript
                      application/json
                      application/xml
                      application/xml+rss;

    include /etc/nginx/conf.d/*.conf;
}

Nếu muốn tìm hiểu thêm về các thông số trong cấu hình Gzip trên nginx, bạn có thể đọc bài Cấu hình nginx gzip như thế nào?, trong bài này mình đã giải thích khá cụ thể về nó.

Tham khảo cấu hình của mình: nginx.confdefault.conf.

3. Kiểm tra

Như cấu hình trên:

  • Varnish sử dụng cổng :80
  • nginx sử dụng cổng :8080

Khởi động lại varnish và nginx:

service nginx restart
service varnish restart

Kiểm tra bằng lệnh xem varnish và nginx đã hoạt động đúng cổng chưa. Và xem header của trang chủ:

netstat -ntlup
curl -I http://us.saungon.com
Kết quả tương tự như hình là bạn đã cài thành công.

Kết quả tương tự như hình là bạn đã cài thành công.

Để xóa cache các bạn dùng lệnh sau, hoặc đơn giản hơn là khởi động lại dịch vụ varnish:

varnishadm "ban req.url ~ /"

Hãy để lại bình luận bên dưới nếu bạn cần trợ giúp!

28 Responses

  1. Mình thấy thông thường kết hợp Varnish với Apache để tận dụng khả năng cache static của Varnish, còn đối với Nginx thì bản thân nó đã handle rất tốt static content rồi nên không cần cài thêm nữa. Bạn nghĩ sao về vấn đề này nhỉ?

    • Sáu Ngón says:

      Bạn nói không sai, theo thực tế mình sử dụng thì varnish chỉ có tác dụng thực sự khi có lượng truy cập lớn mà thôi. Lúc đó varnish sẽ giúp giảm tải cpu, ram cho server rất đáng kể, cho nên tỉ lệ response sẽ cao hơn nhiều.

      Còn với lượng truy cập ít, không xài varnish sẽ cho tốc độ cao hơn. Tuy nhiên cpu, ram cũng sẽ ngốn hơn.

      Có thể hiểu nôm na:
      – Varnish là xe tải: khi không chở hàng nó chạy chậm hơn xe con. Khi chở một lượng hàng lớn nó vẫn có thể chạy với tốc độ ổn định.
      – nginx là xe con: bình thường nó chạy rất nhanh, nhưng khi chở lượng hàng giống như xe tải, có lẽ nó chạy không nổi.

  2. tinhbk says:

    Của mình khi dùng netstat kiểm tra không hiểu sao nginx lại dùng 2 cổng 8080 và 80.

    tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 12449/nginx
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12449/nginx

    Các website vào thì lại về trang index mặc định của VPS. Cậu gặp tình huống này bao giờ chưa?

    • Sáu Ngón says:

      Thông tin bạn cung cấp là rất ít, nên mình chỉ có thể trả lời là “có thể” thôi nhé:

      Lỗi thứ 1: bạn quên chưa config port cho nginx trong file /etc/nginx/conf.d/default.conf.
      Lỗi thứ 2: cấu hình virtual host cho mỗi domain chưa đúng, hoặc quên chưa restart web service.

      Mấy cái này là lỗi cơ bản thôi, nhưng mình phải biết rõ bạn đã làm những gì thì mới có câu trả lời chính xác được.

  1. 28/08/2015

    […] […]

  2. 28/08/2015

    […] website của bạn đang sử dụng mã nguồn WordPress, và chạy trên webserver nginx + Varnish cache thì chắc chắn bạn sẽ gặp lỗi này. Lỗi này xảy ra khi bạn truy cập […]

Leave a Reply

Your email address will not be published. Required fields are marked *