+7

Tìm hiểu tổng quan về Nginx

1. Lời mở đầu

Hí anh em, đến hẹn lại lên, hôm nay mình lại có dịp tìm hiểu kĩ hơn về những kiến thức mới cũng như là các kiến thức, công nghệ mà mình đã và đang sử dụng.

Vào một ngày đẹp trời giữa cái tiết hè oi ả, bạn muốn public ứng dụng Web của bạn cho mọi người sử dụng và bắt đầu tìm kiếm một con Web server đủ ngon để có thể host em nó lên. Search Google thì ra một đống các web server như Apache, Nginx , IIS, Google Server,... Và đây chính là lúc mà bạn nên đưa ra lựa chọn sáng suốt của cuộc đời mình đó chính là Nginx. Vậy Nginx là gì? Nó hoạt động như thế nào? Nó có những tính năng gì? Và nên sử dụng nó thế nào cho tốt đây?

Giờ thì hãy cùng mình tìm hiểu kĩ hơn về nó nhé 😄

2. Nginx là gì?

image.png

Nginx là một máy chủ Web Server mã nguồn mở. Dự án Nginx được phát hành và sử dụng như một web server được thiết kế hướng đến mục đích cải thiện tối đa hiệu năng và sự ổn định. Bên cạnh đó, nhờ vào các khả năng của máy chủ HTTP mà NGINX còn có thể hoạt dộng như một proxy server cho email (IMAP, POP3, và SMTP), reverse proxy, và trung gian để cân bằng tải cho các máy chủ HTTP, TCP, và UDP.

Những công ty lớn sử dụng Nginx bao gồm: Autodesk, Atlassian, Intuit, T-Mobile, GitLab, DuckDuckGo, Microsoft, IBM, Google, Adobe, Salesforce, VMWare, Xerox, LinkedIn, Cisco, Facebook, Target, Citrix Systems, Twitter, Apple, Intel và rất nhiều công ty khác. Vậy là đủ để thấy độ tín dụng của Nginx với cộng đồng rồi 😄

Với mục tiêu của Nginx là tối ưu hóa hiệu suất, nên nó thường vượt mặt các máy chủ web phổ biến khác trong các bài kiểm tra chất lượng benchmark. Đặc biệt trong các trường hợp cần phục vụ nội dung tĩnh (file hình ảnh, css, js, text,..) và/hoặc các yêu cầu truy vấn đồng thời số lượng lớn (high concurrent request).

Nginx còn là 1 trong số ít những máy chủ được viết để giải quyết vấn đề C10K. Hiểu đơn giản thì do các máy chủ web truyền thống xử lý các yêu cầu dựa trên luồng (thread), tức là mỗi khi máy chủ web nhận được 1 yêu cầu mới thì nó sẽ tạo ra 1 luồng mới để xử lý yêu cầu này, và cứ thế khi số lượng các yêu cầu gửi đến máy chủ web ngày càng nhiều thì số lượng các luồng xử lý này trong máy chủ sẽ ngày càng tăng. Điều này dẫn đến việc thiếu hụt tài nguyên cấp cho các luồng xử lý trên. Còn với Nginx, nó không dựa trên luồng để xử lý yêu cầu mà nó sử dụng 1 kiến trúc bất đồng bộ hướng sự kiện linh hoạt. Kiến trúc này sử dụng ít, nhưng quan trọng hợn, là lượng bộ nhớ có thể dự đoán được khi hoạt động.

3. Nginx hoạt động như thế nào?

image.png

Về cơ bản, Nginx hoạt động cũng tương tự như những Web Server khác. Thông thường, khi người dùng truy cập trang Web, browser sẽ kết nối với Server chứa trang Web này. Sau đó, Server sẽ tìm đúng file yêu cầu của Website và gửi lại cho người dùng, Đây được gọi là trình tự xử lý Single Thread hay cấu trúc luồng. Nghĩa là các bước chỉ thực hiện đúng theo một quy trình duy nhất. Và mỗi yêu cầu sẽ được tạo cho một Thread riêng biệt.

Tuy nhiên, nguyên lý hoạt động của Nginx có sự khác biệt ở chỗ nó hoạt động theo dạng kiến trúc bất đồng bộ, theo hướng sự kiện nhằm sử dụng ít bộ nhớ và tăng khả năng chạy đồng thời. Cụ thể, Nginx cho phép các Threads tương đồng với nhau cùng được quản lý trong cùng một tiến trình - Process. Tức là, mỗi Process sẽ bao gồm nhiều thực thể nhỏ hơn – và Worker Connections sẽ làm nhiệm vụ xử lý tất cả Threads đó.

Theo đó, các Worker Connections chính là bộ phận gửi yêu cầu cho Worker Process, và Worker Process lại tiếp tục gửi nó cho Master Process. Cuối cùng, Master Process sẽ đáp ứng các yêu cầu về cho người dùng. Đó cũng là lý do vì sao mỗi Worker Connections lại có thể xử lý được hàng ngàn yêu cầu tương tự nhau. Nhờ vậy, Nginx cũng có thể xử lý hàng ngàn yêu cầu khác nhau cùng một lúc.

4. Nginx có những tính năng gì?

image.png Hiện nay, máy chủ HTTP Nginx sở hữu nhiều tính năng nổi bật như:

  • Tạo ra khả năng xử lý hơn đến 10.000 kết nối cùng một lúc với các bộ nhớ thấp.
  • Hỗ trợ phục vụ các tập tin tĩnh và lập ra các chỉ mục tập tin phù hợp.
  • Có khả năng tăng tốc reverse proxy bằng các bộ nhớ đệm giúp cân bằng tải đơn giản hơn với khả năng chịu lỗi vô cùng cao.
  • Nginx có thể hỗ trợ tăng tốc cùng với bộ nhớ FastCGI, uwsgi, SCGI và những máy chủ memcached vô cùng hiệu quả.
  • Kiến trúc modular cho phép bạn gia tăng tốc độ nạp trang bằng biện pháp nén gzip một cách tự động.
  • Nginx có khả năng hỗ trợ thực hiện mã hóa SSL và TLS.
  • Cấu hình của Nginx vô cùng linh hoạt giúp lưu lại nhật ký truy vấn một cách dễ dàng.
  • Nginx có khả năng chuyển hướng lỗi 3XX-5XX.
  • Rewrite URL có thể sử dụng expression.
  • Nginx có thể hạn chế tỷ lệ đáp ứng của truy vấn.
  • Nginx giúp giới hạn số kết nối đồng thời cũng như truy vấn từ 1 địa chỉ.
  • Nginx có khả năng nhúng mã PERL một cách dễ dàng.
  • Nginx có thể hỗ trợ và tương thích hoàn toàn với IPv6.
  • Nginx có thể hỗ trợ cho websockets.
  • Nginx hỗ trợ truyền tải các file FLV và MP4.

5. So sánh Nginx và Apache

Chúng ta sẽ cùng thực hiện so sánh một giữa 2 Web Servers phổ biến bậc nhất hiện nay xem sao nhé:

Đầu tiên là chúng giống nhau ở một số đặc điểm sau:

  • Đều có khả năng chạy được trên nhiều hệ điều hành của hệ thống UNIX.
  • Có hệ thống Mailing và diễn đàn Stack Overflow hỗ trợ.
  • Có khả năng bảo mật tốt cho mã nguồn.
  • Nginx kết nối với PHP có khả năng xử lý đồng thời như Apache ghép nối với các Module PHP-FPM.
  • Hai server có hiệu năng trên nội dung động tương tự nhau.
  • Thời gian chạy trong môi trường PHP của hai server trên khá giống nhau.
  • Đều có cộng đồng sử dụng lớn

Tuy nhiên, sự khác nhau được thể hiện như sau:

Nginx Apache
Hệ điều hành hỗ trợ Cũng chạy trên một số Unix hiện đại và hỗ trợ một số tính năng cho Windows. Tuy nhiên, hiệu suất hoạt động của Nginx trên windows không mạnh như Apache. Chạy trên tất cả các loại hệ thống Unix-like và hỗ trợ đầy đủ cho Windows.
Hỗ trợ người dùng Chạy trên tất cả các loại hệ thống Unix-like và hỗ trợ đầy đủ cho Windows. Thiếu sự hỗ trợ người dùng từ phía công ty (Apache Foundation)
Nội dung tĩnh Có khả năng xử lý đến 1000 kết nối với nội dung tĩnh nhanh gấp 2.5 lần so với Apache. Sử dụng ít bộ nhớ hơn. Xử lý cùng lúc ít kết nối và tốc độ không được nhanh như Nginx.
Khả năng tương thích Vào năm 2016, Nginx mới bắt đầu hỗ trợ cho Dynamic Module. Có lợi thế hơn do Apache được cung cấp Dynamic Module từ rất lâu.

Cả Nginx web server và Apache web server đều có những thế mạnh riêng. Nginx là người chiến thắng rõ ràng đối với các nội dung tĩnh, trong khi nội dung động không tạo ra sự khác biệt thực sự giữa các máy chủ web. Còn Apache xuất sắc hơn xét về tính linh hoạt, đặc biệt đối với shared hosting user. Tệp .htaccess của Apache và các mô-đun động chắc chắn sẽ phù hợp hơn, trong khi Nginx sẽ tốt hơn cho VPS và dedicated hosting.

Nếu bạn đang chạy một trang web có lưu lượng truy cập cao với nhiều nội dung tĩnh, Nginx có thể là một lựa chọn thông minh để xem xét. Ngoài ra, nếu bạn coi trọng cộng đồng hỗ trợ và sự giàu có của tài nguyên mà nó cung cấp, Apache là một lựa chọn thuận tiện. Từ đây, nhìn vào mọi người có thể chọn lọc ra các tiêu chí và quyết định sử dụng web server nào tùy vào dự án của mình, nhưng có độ ảnh hưởng cao nhất thì các bạn nên cân nhắc về mặt hệ điều hành hỗ trợ, độ hỗ trợ người dùng, sau cùng là hiệu năng. Hoặc có thể lựa chọn sử dụng cả 2 cũng được, NGINX sẽ đứng trước Apache và đóng vai trò như một server proxy, tận dụng được lợi thế của NGINX với tốc độ xử lý nhanh và khả năng thiết lập lượng lớn các kết nối đồng thời, có thể tham khảo cấu trúc dưới nếu muốn kết hợp 2 Web Servers:

image.png

6. Sử dụng nginx thế nào cho tốt?

Nginx là một giải pháp hoàn hảo có thể giúp dự án của bạn rất nhiều thứ. Việc hiểu rõ nginx làm được những gì sẽ giúp bạn tùi chỉnh nó cho phù hợp nhất với dự án của bạn. Mình đã tìm hiểu được một số cách khá hay sau đây để tận dụng Nginx tốt hơn:

Loại bỏ các limitation ở tầng kernel

Để có thể tận dụng tốt nginx thì đôi khi có nhiều limit ở tầng kernel vốn được setup default mà không phù hợp. Những setting dưới đây được chỉnh ở file /etc/sysctl.conf:

  • net.core.somaxconn: Đây là số lượng connection max mà được nginx queue (buffering) trước khi xử lý. Access càng nhiều -> nginx sẽ không xử lý kịp và phải buffer vào queue, queue càng lớn, buffer càng nhiều, block càng ít, sẽ làm nginx tăng lên tương đối.

  • net.ipv4.iplocalportrange: Khi sử dụng nginx dưới dạng một reverse proxy, thì mỗi một connection đến proxy sẽ sử dụng một ephemeral ports, do đó khi access nhiều sẽ dấn đên nhanh hết port, dấn đến blocking. Tăng chỉ số này sẽ giúp connection đến upstream được nhiều hơn, giúp ít blocking hơn.

  • sys.fs.filemax: Đây là số file descriptor max mà linux server có thể sử dụng được, mà như bạn đã biết socket trên linux là file, do đó chỉ số này càng lớn, nginx mở đc càng nhiều socket, sẽ giúp cho max connection tăng.

  • net.ipv4.tcpwmem và net.ipv4.tcprmem: đây là 2 chỉ số của kernel để buffering cho TCP/IP. Nói chung là càng to càng tốt.

Dưới đây là bộ config được recommend cho nginx server:

net.ipv4.ip_local_port_range='1024 65000'
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog='4096'
net.core.rmem_max='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480'
net.ipv4.tcp_max_tw_buckets='400000'
net.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_syn_retries='2'
net.ipv4.tcp_synack_retries='2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'

Phân tích log nginx để tìm bottle neck

Phân tích access log từ nginx sẽ giúp bạn biết bottle neck ở đâu, có một tool rất đơn giản là https://github.com/matsuu/kataribe.

Để sử dụng tool này thì bạn cần setting nginx log format sử dụng directive:

log_format with_time '$remote_addr - $remote_user [$time_local] '
                                      '"$request" $status $body_bytes_sent '
                                      '"$http_referer" "$http_user_agent" $request_time';
access_log /var/log/nginx/access.log with_time;

Caching with nginx

Nginx khi sử dụng để server static file thì bạn nên để ý kĩ các setting về cache, và compression. Setting sử dụng gzip cho static file cũng rất quan trọng. Sử dụng gzip sẽ giúp giảm rất nhiều cost liên quan đến IO, và đường truyền. Setting cache control sẽ giúp server không request lại static file đó nữa cho đến khi cache expire. Bạn có thể tham khảo setting dưới đây.

http {
    gzip              on;
    gzip_http_version 1.0;
    gzip_types        text/plain
                      text/html
                      text/xml
                      text/css
                      application/xml
                      application/xhtml+xml
                      application/rss+xml
                      application/atom_xml
                      application/javascript
                      application/x-javascript
                      application/x-httpd-php;
    gzip_disable      "MSIE [1-6]\.";
    gzip_disable      "Mozilla/4";
    gzip_comp_level   1;
    gzip_proxied      any;
    gzip_vary         on;
    gzip_buffers      4 8k;
    gzip_min_length   1100;
}

Khi sử dụng nginx dưới dạng reverse proxy, nếu memory của bạn thừa thãi, và lượng data để response cũng không lớn bạn có thể set để nginx cache trên memory thay vì trên file

proxy_cache_path /dev/shm/nginx levels=1:2 keys_zone=czone:16m max_size=32m inactive=10m;

Advance nginx

Một setting cũng rất hay được sử dụng là keepalive. Thông thường keep alive là một technique của http giúp "giữ" connection TCP lại ngay cả khi HTTP connection session đã kết thúc, để có thể reuse lại cho request tiếp theo. Trong trường hợp implement thường HTTP client tạo 1 kết nối TCP tới server đích, gửi request và nhận response. Sau đó server đóng lại kết nối.

Technique này rất có lợi khi mà thông thường một user sẽ gửi rất nhiều request để lấy cả static resource.

Để tìm hiểu kĩ hơn về mục đihcs của technique này, bạn có thể đọc thêm ở đây https://www.nginx.com/blog/http-keepalives-and-web-performance/

Sử dụng keepalive trên nginx rất đơn giản bằng cách thêm directive keepalive vào trong upstream section

upstream app {
  server 127.0.0.1:5000;
  keepalive 16;
}

Tham khảo thêm các config khác tại đây.

Tổng kết

Vậy là mình đã tổng kết lại được những điểm tổng quan về Nginx mà mình tìm tòi được. Bên cạnh đó là những so sánh giữa Nginx và Apache để mọi người có thể đưa ra lựa chọn phù hợp cho mỗi dự án. Và cuối cùng là những cấu hình giúp tận dụng Nginx hoạt động một cách tốt hơn.

Trên đây là những kiến thức mà mình tổng hợp lại từ documentation của Nginx và nhiều nguồn khác nhau. Mình cũng mới tìm hiểu kĩ hơn về Nginx nên bài viết có thể còn nhiều thiếu sót, mọi người nếu có thắc mắc hoặc vấn đề gì thì hãy comment để cùng khắc phục và tìm hiểu thêm nhé 😄

Cảm ơn các bạn đã dành thời gian theo dõi bài viết của mình!

Tài liệu tham khảo

  1. http://nginx.org/en/docs/
  2. https://viblo.asia/p/tim-hieu-tong-quan-ve-nginx-Az45bzXo5xY
  3. https://viblo.asia/p/giup-website-cua-ban-nhanh-len-gap-n-lan-voi-nginx-aWj532qol6m
  4. https://www.linode.com/docs/guides/slightly-more-advanced-configurations-for-nginx/

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.