Vấn đềHôm nay tôi đã gặp một trở ngại khi xây dựng bộ lọc tìm kiếm phức tạp cho một khách hàng. Ứng dụng tạo ra các yêu cầu GET khổng lồ bằng cách truyền các trạng thái bộ lọc lồng nhau và các mảng dài trực tiếp qua URL. Mọi thứ hoạt động hoàn hảo ở môi trường phát triển cục bộ. Tuy nhiên, ngay khi chúng tôi triển khai lên máy chủ staging phía sau Nginx, trình duyệt bắt đầu báo lỗi 414 Request-URI Too Large.
Nginx mặc định khá khắt khe. Nó giới hạn độ dài URI để ngăn chặn các cuộc tấn công Từ chối Dịch vụ (DoS), nơi kẻ tấn công cố gắng làm cạn kiệt bộ nhớ bằng các header vô tận. Mặc dù các giá trị mặc định này giúp bảo vệ bạn, nhưng các ứng dụng web hiện đại thường cần nhiều không gian hơn cho các URL chứa nhiều trạng thái hợp lệ.
Quy trình DebugĐầu tiên, tôi phải xác nhận liệu Nginx có thực sự là nút thắt cổ chai hay không. Kiểm tra log truy cập là cách nhanh nhất để xác minh điều này. Tôi đã chạy một lệnh tail đơn giản để theo dõi lưu lượng truy cập trong thời gian thực:
tail -f /var/log/nginx/access.log
Dòng log rất rõ ràng. Nó hiển thị mã trạng thái 414 ngay lập tức:
127.0.0.1 - - [03/Jun/2026:14:22:10 +0000] "GET /api/search?filters=...[chuỗi rất dài]... HTTP/1.1" 414 150 "-" "Mozilla/5.0..."
Tiếp theo, tôi sử dụng curl để kiểm tra các header phản hồi. Bước này đảm bảo lỗi không đến từ middleware cấp ứng dụng hoặc bộ cân bằng tải ở phía trước:
curl -I "http://localhost/api/search?url_rat_dai_o_day..."
Kết quả xác nhận Nginx chính là nguyên nhân:
HTTP/1.1 414 Request-URI Too Large
Server: nginx/1.18.0 (Ubuntu)
Content-Type: text/html
...
Giải phápĐể khắc phục điều này, tôi cần tinh chỉnh các cài đặt bộ đệm. Bạn chủ yếu cần quan tâm đến hai chỉ thị: client_header_buffer_size và large_client_header_buffers.
Bước 1: Mở tệp cấu hìnhBạn có thể áp dụng các thay đổi này trên toàn cầu trong nginx.conf, nhưng tôi thích nhắm mục tiêu vào các khối server cụ thể hơn. Cách tiếp cận này giúp giữ mức sử dụng bộ nhớ thấp cho các trang web khác trên cùng một máy.
sudo nano /etc/nginx/sites-available/default
Bước 2: Tăng kích thước bộ đệmThêm hoặc sửa đổi các dòng này bên trong khối http, server, hoặc location của bạn. Trong hầu hết các trường hợp, khối server là vị trí tốt nhất:
server {
listen 80;
server_name example.com;
# Tăng bộ đệm ban đầu cho các dòng yêu cầu và header
client_header_buffer_size 16k;
# Thiết lập số lượng và kích thước bộ đệm cho các yêu cầu lớn hơn
# Định dạng: [số lượng] [kích thước]
large_client_header_buffers 4 32k;
location / {
proxy_pass http://localhost:3000;
}
}
Những con số này thực sự có ý nghĩa gì?
client_header_buffer_size: Nginx sử dụng giá trị này cho dòng yêu cầu ban đầu. Mặc định thường là 1k. Nếu URI lớn hơn mức này, Nginx sẽ cố gắng sử dụng bộ đệm 'lớn' (large).-large_client_header_buffers: Chỉ thị này chỉ định kích thước tối đa cho một header lớn duy nhất. Việc đặt giá trị này thành4 32kcho phép URI lên tới 32k. Chrome và Edge thường giới hạn URL ở mức 32k, vì vậy cấu hình này bao quát hầu hết các giới hạn của trình duyệt hiện đại.### Bước 3: Kiểm tra và Tải lạiĐừng chỉ khởi động lại Nginx. Luôn kiểm tra cú pháp trước để tránh làm trang web của bạn bị ngoại tuyến:
sudo nginx -t
Nếu bài kiểm tra vượt qua, hãy tải lại cấu hình để áp dụng các thay đổi:
sudo systemctl reload nginx
Xác minhTôi quay lại ứng dụng và làm mới trang. Kết quả tìm kiếm được tải ngay lập tức. Để chắc chắn, tôi đã chạy một bài kiểm tra curl cuối cùng với cùng một URL dài đó. Cuối cùng nó đã trả về 200 OK.
Bài học kinh nghiệmSửa lỗi bộ đệm là một giải pháp nhanh chóng, nhưng lỗi 414 thường là dấu hiệu của các vấn đề kiến trúc sâu hơn. Hãy xem xét các điểm sau trước khi tiếp tục:
- Chuyển sang POST: Nếu chuỗi truy vấn của bạn đủ dài để làm hỏng máy chủ, nó nên nằm trong thân JSON. GET dùng để lấy dữ liệu; POST dùng để gửi dữ liệu phức tạp.- Rút ngắn trạng thái: Thay vì nhồi nhét một đối tượng khổng lồ vào URL, hãy lưu trữ các bộ lọc trong cơ sở dữ liệu. Thay vào đó, hãy truyền một
?id=123đơn giản.- Hiệu suất Cache: Các URL dài và duy nhất là "ác mộng" đối với các CDN. Chỉ một thay đổi ký tự nhỏ thường gây ra lỗi cache (cache miss), làm chậm ứng dụng của bạn cho mọi người.- Bảo mật bộ nhớ: Tránh đặt bộ đệm thành các giá trị khổng lồ như 512MB. Các bộ đệm lớn tiêu tốn RAM trên mỗi kết nối, giúp kẻ xấu dễ dàng làm sập máy chủ của bạn hơn.Đối với hầu hết các môi trường production hiện đại,16khoặc32kcung cấp một sự cân bằng hoàn hảo giữa chức năng và bảo mật.

