Tối ưu hóa hiệu suất Nginx: Xử lý HTTP và cấu hình
12 phút đọc - 26 tháng 5, 2026

Tối ưu hóa các quy trình làm việc, bộ đệm, keepalive và cân bằng tải của Nginx để xử lý hơn 50.000 yêu cầu mỗi giây trên một máy chủ duy nhất.
Quy trình xử lý HTTP của Nginx: Tối ưu hóa cấu hình
Cấu hình mặc định của Nginx được thiết kế để đảm bảo tính tương thích, không phải hiệu suất. Với việc điều chỉnh phù hợp, một máy chủ duy nhất có thể xử lý từ 50.000 đến 80.000 yêu cầu mỗi giây. Hướng dẫn này bao gồm các thiết lập quan trọng nhất: quy trình làm việc, kết nối, keepalive, đệm, cân bằng tải và cách xác minh các thay đổi của bạn bằng các bài kiểm tra hiệu năng.
Cách Nginx xử lý các yêu cầu HTTP
Nginx xử lý các yêu cầu theo các giai đoạn riêng biệt, mỗi giai đoạn đều tiêu tốn tài nguyên hệ thống. Hiểu được quy trình này sẽ giúp bạn xác định các cài đặt phù hợp.
Quá trình bắt đầu ở cấp độ kernel. Các kết nối đến được đưa vào hàng đợi SYN và ACCEPT, và các tiến trình làm việc của Nginx sẽ nhận chúng. Sau khi được chấp nhận, tiến trình làm việc sẽ phân tích yêu cầu HTTP từ bộ đệm kernel. Lưu lượng TLS khiến bước này tiêu tốn nhiều CPU hơn.
Tiếp theo, Nginx khớp yêu cầu với một máy chủ ảo bằng cách sử dụng tiêu đề Host và kết hợp IP/cổng, sau đó giải quyết URI thành một khối vị trí thông qua khớp tiền tố hoặc biểu thức chính quy.
Đối với nội dung động, Nginx chuyển tiếp yêu cầu đến một máy chủ phía sau (FastCGI, proxy). Giai đoạn giao tiếp phía sau này được hưởng lợi rất nhiều từ các kết nối liên tục. Nếu không có tính năng keepalive phía sau, Nginx sẽ mở một kết nối TCP mới cho mỗi yêu cầu, làm tăng độ trễ và tải CPU.
Nếu proxy_buffering được bật, Nginx sẽ đọc toàn bộ phản hồi từ máy chủ phía sau vào bộ nhớ trước khi gửi nó đến máy khách. Điều này giúp giải phóng công việc cho nhân viên để xử lý các yêu cầu mới ngay lập tức. Cuối cùng, trong quá trình gửi đầu ra, việc bật sendfile cho phép truyền tải zero-copy, giúp tăng thông lượng từ khoảng 6 Gbps lên 30 Gbps.
Mỗi giai đoạn đều tiêu tốn bộ đệm bộ nhớ, bộ mô tả tệp và chu kỳ CPU. Các phần dưới đây tập trung vào từng điểm nghẽn.
Các quy trình và kết nối của công nhân
Bắt đầu với worker_processes auto; trong bối cảnh chính của bạn. Điều này sẽ khớp số lượng worker với số lõi CPU của bạn. Trên một VPS có số lõi giới hạn, hãy đặt số lượng này thủ công (ví dụ: worker_processes 2;). Nếu khối lượng công việc của bạn tiêu tốn nhiều bộ nhớ, hãy cân nhắc giảm số lượng worker để tránh sử dụng quá mức RAM.
Bật worker_cpu_affinity auto; để gán mỗi worker vào một lõi cụ thể. Điều này giúp giảm thiểu lỗi cache và chuyển đổi ngữ cảnh. Tính năng này có sẵn từ Nginx 1.9.10.
Giới hạn kết nối
Lệnh worker_connections định hướng này thiết lập số lượng kết nối đồng thời mà mỗi worker có thể xử lý. Tổng dung lượng là worker_processes × worker_connections. Giá trị mặc định là 512 hoặc 1.024, quá thấp cho môi trường sản xuất. Hãy đặt thành 2.048 hoặc 4.096 cho mỗi worker đối với các trang web có lưu lượng truy cập cao.
Mỗi kết nối cần ít nhất một bộ mô tả tệp. Trong thiết lập proxy ngược, mỗi kết nối sử dụng hai bộ mô tả tệp (một cho máy khách, một cho máy chủ nguồn). Đặt worker_rlimit_nofile giá trị này ít nhất gấp đôi worker_connections với một khoảng trống dự phòng. Đối với worker_connections 4096;, hãy sử dụng worker_rlimit_nofile 10000; hoặc cao hơn
Ở cấp độ hệ thống, hãy tăng fs.file-max lên /etc/sysctl.conf lên ít nhất 500.000 và thiết lập LimitNOFILE=65535.
Cuối cùng, thêm multi_accept on; vào khối sự kiện để các worker chấp nhận tất cả các kết nối đang chờ cùng một lúc thay vì từng kết nối một.
Thời gian chờ và Keepalive
Keepalive của máy khách
Tham số keepalive_timeout chỉ thị này kiểm soát thời gian kết nối khách hàng không hoạt động vẫn được duy trì. Đối với các máy chủ có lưu lượng truy cập cao, khoảng 30 đến 65 giây là phù hợp. Sử dụng dạng hai tham số:
keepalive_timeout 65s 60s;Giá trị đầu tiên là thời gian chờ phía máy chủ. Giá trị thứ hai gửi Keep-Alive: timeout=60 đầu đề đến client. Đặt giá trị phía client thấp hơn một chút sẽ ngăn chặn các tình huống xung đột khi trình duyệt cố gắng tái sử dụng các kết nối mà Nginx đã đóng.
Chỉ thị keepalive_requests chỉ thị này giới hạn số lượng yêu cầu mà một kết nối duy nhất xử lý trước khi bị ngắt. Giá trị mặc định là 1.000 (được tăng từ 100 trong phiên bản 1.19.10). Đối với các backend ổn định, hãy tăng giá trị này lên 10.000 để giảm sự thay đổi liên tục của kết nối.
Thời gian chờ proxy
proxy_connect_timeout đặt thời gian Nginx chờ để thiết lập kết nối với backend. Giá trị mặc định là 60 giây. Giảm nó xuống còn 5 đến 10 giây để chuyển đổi dự phòng nhanh.
proxy_read_timeout xác định thời gian Nginx chờ giữa các lần đọc liên tiếp từ máy chủ phía sau. Điều chỉnh giá trị này sao cho phù hợp với thời gian chờ thực thi của máy chủ phía sau. Nếu thời gian chờ của PHP-FPM request_terminate_timeout là 120 giây, hãy đặt proxy_read_timeout thành ít nhất 120 giây để tránh lỗi 504 sớm.
proxy_send_timeout điều khiển khoảng thời gian giữa các lần ghi liên tiếp lên máy chủ phía sau. Giá trị mặc định là 60 giây thường là đủ trừ khi bạn đang gửi các nội dung yêu cầu lớn.
Theo quy tắc, proxy_connect_timeout luôn phải là giá trị ngắn nhất trong ba giá trị này.
Kích thước bộ đệm
client_body_buffer_size kiểm soát lượng nội dung yêu cầu đến mà Nginx lưu giữ trong bộ nhớ. Giá trị mặc định là 8k hoặc 16k xử lý các biểu mẫu gửi đơn giản, nhưng việc tải lên tệp sẽ tràn ra đĩa. Tăng giá trị này lên 128k cho các tệp tải lên cỡ nhỏ đến trung bình. Tăng client_max_body_size giá trị mặc định từ 1m nếu người dùng tải lên các tệp lớn hơn.
proxy_buffer_size xử lý các tiêu đề phản hồi riêng biệt với nội dung. Giá trị mặc định là 4k hoặc 8k thường hoạt động tốt, nhưng các ứng dụng có Set-Cookie (thường gặp trong thương mại điện tử) có thể vượt quá giới hạn này, gây ra lỗi 502. Đo kích thước tiêu đề thực tế của bạn:
curl -s -w '%{size_header}' -o /dev/null http://your-upstream-urlLàm tròn lên đến bội số 4k gần nhất.
proxy_buffers đặt số lượng và kích thước của các bộ đệm cho nội dung phản hồi. Giá trị mặc định (8 bộ đệm 4k hoặc 8k, tổng cộng 32k đến 64k) sẽ không chứa được phản hồi JSON lớn. Đo lường phản hồi điển hình lớn nhất của bạn với curl và cấu hình đủ bộ đệm để lưu trữ toàn bộ phản hồi trong RAM.
Hành vi đệm proxy
Với proxy_buffering on (mặc định), Nginx đọc toàn bộ phản hồi từ máy chủ nguồn vào bộ nhớ trước khi gửi đến máy khách. Điều này cho phép các máy chủ phía sau chuyển sang xử lý các yêu cầu mới ngay lập tức.
Đặt proxy_busy_buffers_size thành ít nhất proxy_buffer_size cộng thêm một bộ đệm, nhưng nhỏ hơn tổng dung lượng bộ đệm của bạn. Đối với proxy_buffers 8 16k (tổng cộng 128k), hãy giữ proxy_busy_buffers_size dưới 112k.
Đối với các điểm cuối thời gian thực như Sự kiện do máy chủ gửi (Server-Sent Events) hoặc long-polling, hãy vô hiệu hóa bộ đệm bằng proxy_buffering off trong một khối dành riêng cho vị trí. Áp dụng điều này một cách có chọn lọc cho /stream hoặc /events đường dẫn, không áp dụng toàn cục.
Cân bằng tải và Upstream Keepalive
Theo mặc định, Nginx mở một kết nối TCP mới cho mỗi yêu cầu được proxy. Mỗi lần bắt tay sẽ thêm 10 đến 100 ms độ trễ, với TLS thêm 10 đến 50 ms nữa. Upstream keepalive duy trì một nhóm các kết nối liên tục để loại bỏ chi phí này.
Cần có ba cài đặt:
upstream backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
keepalive 128;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}Tham số keepalive giá trị này thiết lập số kết nối nhàn rỗi tối đa cho mỗi worker. Tính toán kích thước nhóm tối ưu như sau: (workers × target concurrency) / upstream nodes.
Đặt thời gian chờ của máy chủ phía sau keepalive_timeout thành 60 đến 120 giây để phù hợp với cài đặt của backend và xử lý các đợt tăng đột biến lưu lượng.
Chiến lược cân bằng tải
Nginx hỗ trợ một số phương pháp cân bằng tải. Round-robin (mặc định) phân phối các yêu cầu theo thứ tự tuần tự. least_conn định tuyến đến máy chủ có ít kết nối hoạt động nhất, phù hợp với các khối lượng công việc có thời lượng yêu cầu thay đổi. ip_hash Cung cấp tính bền vững phiên bằng cách định tuyến cùng một địa chỉ IP của khách hàng đến cùng một máy chủ phía sau.
Sử dụng tham số weight tham số này khi các máy chủ có công suất khác nhau:
upstream backend {
least_conn;
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080;
server 10.0.1.12:8080 backup;
keepalive 128;
}Máy chủ có trọng số nhận lượng lưu lượng gấp ba lần. Máy chủ backup máy chủ chỉ được kích hoạt nếu tất cả các máy chủ chính đều ngừng hoạt động. Cấu hình max_fails và fail_timeout để kiểm tra tình trạng hoạt động thụ động, và sử dụng max_conns để giới hạn số kết nối đồng thời trên mỗi backend.
Kiểm tra và giám sát
Luôn đo lường hiệu suất cơ bản trước khi thay đổi bất cứ điều gì. Sau mỗi lần thay đổi, hãy tiến hành đánh giá hiệu suất lại. Chỉ thực hiện một thay đổi tại một thời điểm.
Kiểm tra cú pháp cấu hình của bạn bằng nginx -t trước khi tải lại. Chạy các bài kiểm tra hiệu suất từ một máy riêng biệt để tránh xung đột tài nguyên.
wrk là công cụ tiêu chuẩn để kiểm tra tải HTTP:
wrk -t4 -c200 -d30s http://your-server.com/Theo dõi số yêu cầu mỗi giây, độ trễ trung bình, độ trễ tối đa và tốc độ truyền tải. Apache Bench phù hợp cho các bài kiểm tra đơn giản hơn:
ab -n 50000 -c 40 http://your-server.com/Giám sát liên tục
Kích hoạt stub_status để giám sát các kết nối đang hoạt động theo thời gian thực thông qua curl http://localhost/nginx_status.
Thêm các biến thời gian vào định dạng nhật ký của bạn để xác định vị trí xảy ra độ trễ:
$request_timeđể biết tổng thời gian yêu cầu$upstream_connect_timecho thời gian kết nối phía máy chủ$upstream_response_timecho tổng thời gian xử lý phía máy chủ
Kiểm tra nhật ký lỗi để phát hiện các vấn đề về bộ đệm với journalctl -u nginx --no-pager | grep "temporary file". Nếu các phản hồi đang truy cập vào đĩa, proxy_buffers quá nhỏ. Hãy tìm các lỗi "quá nhiều tệp đang mở", điều này cho thấy worker_rlimit_nofile cần tăng lên.
Giảm I/O nhật ký bằng cách ghi nhật ký có đệm:
access_log /var/log/nginx/access.log combined buffer=64k flush=5s;Sử dụng ss -tn state established dst [backend_ip] trong các bài kiểm tra tải để xác minh các kết nối đang được tái sử dụng và không bị dồn ứ trong trạng thái TIME_WAIT.
Đối với máy chủ chuyên dụng và dịch vụ lưu trữ VPS được tối ưu hóa cho khối lượng công việc hiệu suất cao, hãy tham khảo Máy chủ FDC.
Tại sao việc sở hữu một VPS mạnh mẽ và không giới hạn băng thông lại quan trọng
Cần hiệu suất ổn định và lưu lượng không giới hạn? Một VPS mạnh mẽ không giới hạn lưu lượng cung cấp tốc độ, khả năng mở rộng và băng thông mà bạn cần, mà không phải lo lắng về giới hạn sử dụng
3 phút đọc - 9 tháng 5, 2025
Cách tối ưu hóa không gian lưu trữ trên Linux
15 phút đọc - 22 tháng 5, 2026

Bạn có thắc mắc hoặc cần giải pháp tùy chỉnh?
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức