Nginx được biết đến như là một load balancer, cache và webserver hiệu năng cao, được sử dụng bởi 45% các trang web lớn nhất trên thế giới hiện nay. Thường thì các cấu hình mặc định trên Nginx và Linux làm việc khá tốt và hiệu quả, nhưng đôi khi hệ thống đòi hỏi chúng ta cần phải điều chỉnh một chút để giúp tối ưu hóa tài nguyên sử dụng. Trong bài viết này, mình sẽ chỉ cho các bạn biết một số các thiết lập trên Linux và Nginx quan trọng khi muốn tuning hệ thống.
Xem thêm: Hướng dẫn tuning performance network TCP Congestion
Đối với hệ thống Linux và NginX, bạn có thể điều chỉnh hầu hết các thiết lập, nhưng trong bài viết này, mình chỉ tập trung vào một số thiết lập có lợi nhất cho user. Có một số thiết lập mà mình khuyên bạn thay đổi chỉ khi bạn đã hiểu sâu về Nginx và Linux.
Điều chỉnh cấu hình Linux
Các thiết lập trong Linux kernel (từ phiên bản 2.6 trở lên) khá phù hợp cho hầu hết các mục đích sử dụng chung, nhưng thay đổi một số cấu hình trong đó có thể sẽ đem lại nhiều lợi ích cho hệ thống của bạn. Trước hết bạn nên kiểm tra kernel log để xem các thiết lập cấu hình có thấp quá không, rồi sau đó điều chỉnh lại. Ở đây mình chỉ đề cập đến những thiết lập góp phần đem lại nhiều lợi ích nhất trong điều kiện hệ thống hoạt động bình thường.
Backlog Queue
Các thiết lập dưới đây liên quan đến các kết nối và cách chúng được đưa vào queue. Nếu bạn có tỷ lệ các kết nối đến NGINX cao và hiệu suất không đồng đều theo thời gian, thì việc thay đổi các thiết lập này có thể giúp ích khá nhiều cho bạn.
- net.core.somaxconn – số các kết nối tối đa có thể được queued lại để được chấp nhận. Mặc định giá trị này rất thấp và con số đó thường được chấp nhận bởi vì NGINX chấp nhận các kết nối rất nhanh, nhưng cũng đáng để chúng ta điều chỉnh cao lên chút nếu như traffic đi vào hệ thống website của bạn lớn.
- net.core.netdev_max_backlog – tỷ lệ các packets được buffered bởi card mạng trước khi đưa cho CPU xử lý. Tăng giá trị này có thể giúp cải thiện performance trên máy với băng thông cao. Kiểm tra kernel log để xem có lỗi nào liên quan đến thiết lập này không, nếu có thì hãy xem thêm tài liệu về card mạng đang sử dụng để điều chỉnh con số sao cho phù hợp.
File Descriptor
File Descriptors là những tài nguyên mà hệ điều hành sử dụng để thể hiện các kết nối và file được mở, và một số thứ khác nữa. NGINX có thể sử dụng đến hai file descriptors cho mỗi kết nối. Ví dụ, nếu NGINX có tác dụng là proxy, nó thường sử dụng một file descriptor cho kết nối client và một file descriptor khác cho kết nối tới proxied server, mặc dù tỷ lệ này thấp hơn nếu HTTP keepalive được dùng. Đối với một hệ thống phục vụ lượng kết nối lớn, các thiết lập sau đây có thể rất cần thiết để bạn điều chỉnh lại.
sys.fs.file-max
– giới hạn mở rộng file descriptorsnofile
– giới hạn file descriptor dành cho user, thiết lập trong file /etc/security/limits.conf
Port tạm thời
Khi NGINX hoạt động với vai trò proxy, mỗi kết nối tới một upstream server sẽ sử dụng một port tạm thời. Bạn có thể sẽ muốn thay đổi lại thiết lập này.
- net.ipv4.ip_local_port_range – là dãy port cho phép. Nếu bạn thấy NGINX đang chạy ngoài dãy port này, thì tăng dãy port cao lên. Thiết lập port phổ biến từ 1024 cho đến 65535 là ok.
Điều chỉnh cấu hình NGINX
Dưới đây là một số directive NGINX có thể tác động lớn đến performance. Như mình đã trình bày ở trên, mình chỉ thảo luận các directives an toàn để bạn tự điều chỉnh. Mình khuyên bạn không nên thay đổi các thiết lập cũng như những directive khác mà không có hướng dẫn từ NGINX.
Worker Processes
NGINX có thể chạy nhiều worker process, mỗi process có khả năng xử lý số lượng lớn các kết nối đồng thời. Bạn có thể kiểm soát số worker process và cách chúng xử lý các kết nối với các directive sau đây:
- worker_process – số worker process (mặc định là 1). Thường thì việc chạy một worker process trên mỗi CPU hoạt động khá tốt, và mình khuyên bạn nên thiết lập directive này thành auto. Có một số thời điểm khi bạn muốn tăng con số này lên, như là khi worker process phải thực hiện rất nhiều hoạt động đọc ghi đĩa.
- worker_connnections – số connection tối đa mỗi worker process có thể xử lý đồng thời. Mặc định là 512, nhưng hầu hết các hệ thống đều cần phải có đủ tài nguyên để có thể phục vụ con số này khi mà tăng giá trị lên. Thiết lập thích hợp phụ thuộc vào size của server và lượng traffic tự nhiên, và có thể cần phải được thử nghiệm thông qua benchmark.
Keepalive Connections
Keepalive Connections có thể có một tác động lớn đến performance bằng cách giảm thiểu CPU và network cần thiết để mở và đóng các kết nối. NGINX hủy bỏ tất cả các kết nối client và tạo ra các kết nối riêng biệt và độc lập tới upstream server. NGINX hỗ trợ keepalives cho cả client và upstream server.
Các directive sau đây liên quan đến keepalive client.
- keepalive_requests – số request một client có thể tạo qua một keepalive connection. Mặc định số này là 100, nhưng khi thiết lập giá trị này cao hơn, có thể sẽ cực kỳ hữu ích cho việc testing với các công cụ tạo load – cụ thể hơn là công cụ gửi số lượng lớn request từ một client.
- keepalive_timeout – keepalive connection nhàn rỗi được mở trong bao lâu.
Directive sau đây liên quan đến upstream server:
- keepalive – số keepalive connection nhàn rỗi cho một upstream server mà vẫn mở cho mỗi worker process. Không có giá trị mặc định.
Để kích hoạt keepalive connection cho upstream server, bạn phải đưa các directive sau đây vào trong phần cấu hình.
proxy_http_version 1.1;
proxy_set_header Connection "";
Access Logging
Khi logging lại mọi request dẫn đến việc sử dụng cả CPU lẫn Disk I/O, và một cách để giảm ảnh hưởng bởi việc logging chính là kích hoạt access‑log buffering. Với buffering, thay vì thực hiện hoạt động ghi riêng biệt cho mỗi dòng log, NGINX sẽ bufffer lại một loạt các dòng log và ghi chúng tới file khác với chỉ một hành đồng.
Để kích hoạt access-log buffering, thêm tham số buffer=size vào directive access_log. NginX ghi nội dung buffer tới log khi kích cỡ buffer đạt tới giá trị size. Để cho NGINX ghi buffer sau một khoảng thời gian, thì bạn thêm tham số flush=time vào file cấu hình. Khi cả hai tham số trên đều được thiết lập, NGINX sẽ ghi các dòng log tới file log khi dòng log tiếp theo không còn chỗ trong buffer nữa hoặc log trong buffer đã quá hạn cho phép lưu giữ. Các dòng log cũng được ghi khi worker process đang mở lại các file log hoặc tắt máy. Để tắt access-log, thì bạn chỉ cần thêm tham số off tới directive acccess_log.
Sendfile
Lời gọi hàm sendfile() của hệ điều hành gọi copy dữ liệu từ một file descriptor sang file descriptor khác, thường đạt được bằng zero-copy, có thể tăng tốc truyền dữ liệu TCP. Để kích hoạt NGINX sử dụng tính năng này, thêm directive sendfile vào trong phần http hoặc server hoặc location trong file cấu hình của bạn. NGINX sau đó có thể ghi nội dung được cache hoặc trên disk xuống socket, khiến cho việc ghi dữ liệu cực kỳ nhanh mà lại ít tốn CPU hơn. Tuy nhiên, lưu ý rằng dữ liệu được copy bằng sendfile() bỏ qua user space, nên nó không thuộc chuỗi xử lý như dữ liệu thông thường và các bộ lọc nội dung của NGINX như là gzip. Khi một cấu hình có chứa cả directive sendfile và directive kích hoạt bộ lọc content-changing, khi đó NGINX sẽ tự động vô hiệu hóa sendfile.
Limits
Bạn có thể thiết lập các giới hạn giúp ngăn chặn client sử dụng quá nhiều tài nguyên – có thể ảnh hưởng tới performance của hệ thống cũng như tính security và trải nghiệm người dùng. Dưới đây là các directive bạn nên quan tâm:
- limit_conn và limit_conn_zone – giới hạn số kết nối từ client mà NGINX có thể chấp nhận từ một địa chỉ IP. Thiết lập giá trị này giúp ngăn chặn client mở quá nhiều kết nối và sử dụng nhiều tài nguyên hơn mức client thông thường.
- limit_rate – giới hạn tỷ lệ phản hồi được truyền tới client, đối với mỗi kết nối (vì client có thể mở nhiều kết nối nhưng chỉ nhận được một lượng băng thông nhất định cho mỗi kết nối). Thiết lập limit giá trị này có thể giúp ngăn chặn hệ thống khỏi bị quá tải bởi một số client nhất định, giúp đảm bảo chất lượng dịch vụ cho tất cả các clie lnt khác.
- limit_req và limit_req_zone – giới hạn tỷ lệ các truy vấn được xử lý bởi NGINX, có tác dụng tương tự như limit_rate. Chúng cũng có thể giúp cải thiện tính security, đặc biệt là cho các trang login, bằng cách giới hạn tỷ lệ request với một giá trị hợp lý ở một người dùng thông thường (tránh DDOS).
- max_conns – thiết lập số kết nối đồng thời tối đa được chấp nhận bởi server trong upstream group. Áp dụng giới hạn này giúp ngăn chặn upstream server khỏi bị overload. Thiết lập giá trị này thành 0, nghĩa là không có giới hạn.
- queue (trong NGINX Plus) – tạo queue mà trong đó các request được đặt vào khi tất cả các server trong upstream group đã đạt tới giới hạn max_conns. Directive này thiết lập số request tối đa trong queue, thời gian chờ (mặc định 60s) trước khi lỗi được trả về. Request sẽ không được đặt trong queue nếu như bạn không sử dụng directive này.
Caching và Compression có thể giúp cải thiện Performance
Một số tính năng bổ sung của Nginx có thể được sử dụng để tăng cường performance cho ứng dụng web, tuy không được gọi là tuning, nhưng cũng đáng để bạn phải xem xét bởi những tác động đáng kể của chúng. Bao gồm caching và compression.
Caching
Bằng việc kích hoạt caching trên NGINX, bạn có thể cải thiện đáng kể thời gian phản hồi tới client và giúp giảm tải cho backend server.
Compression
Các truy vấn compression gửi tới client có thể giúp giảm kích thước dữ liệu một cách đáng kể, vì chúng sử dụng ít băng thông network hơn. Mặc dù compression data có sử dụng tài nguyên CPU, nhưng cũng cực kỳ hữu ích khi bạn thực sự muốn giảm thiểu băng thông cho NGINX. Điều quan trọng cần lưu ý là bạn không nên kích hoạt compression cho các đối tượng dữ liệu mà đã được nén sẵn rồi như file hình ảnh JPEG,…