Giới thiệu
Xin chào, trong bài viết lần này tớ sẽ chia sẻ về cách mà tớ đang sử dụng để giúp Nginx đạt được hiệu suất tốt. Thông thường, nếu như nginx được cấu hình đúng thì có thể xử lý tối đa 400k đến 500k request mỗi giây (clustered), hầu hết tớ thấy là 50k – 80k (non-clustered) request mỗi giây và CPU đạt 30% với loại 2 x Intel Xeon
với HyperThreading được bật, nhưng nó có thể hoạt động mà không gặp vấn đề gì trên các máy chậm hơn.
Config này được sử dụng trong môi trường test chứ không phải production, vì vậy nếu bạn muốn áp dụng thì nên tìm cách implement những cái phù hợp cho server của bạn.
Thực hiện
Cài đặt Nginx
Đầu tiên, chúng ta cần cài đặt nginx (bỏ qua nếu bạn đã cài sẵn rồi), ở đây mình dùng ubuntu:
1 2 | <span class="token function">sudo</span> apt <span class="token function">install</span> nginx |
Backup your original configs and you can start reconfigure your configs. You will need to open your nginx.conf at /etc/nginx/nginx.conf with your favorite editor.
config nginx
Tiếp đến chúng ta cần backup config và sau đó bạn có thể cấu hình lại với config mới. Bạn cần mở /etc/nginx/nginx.conf
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | <span class="token comment"># bạn cần set worker processes dựa trên CPU core, nginx không được hưởng từ việc settting nhiều hơn thế</span> <span class="token keyword">worker_processes</span> auto<span class="token punctuation">;</span> <span class="token comment"># một vài version mới sẽ tự động tính toán nó</span> <span class="token comment"># số lượng file descriptors sử dụng cho nginx</span> <span class="token comment"># giới hạn cho các file descriptors trên server thường đưuọc set vởi OS</span> <span class="token comment"># nếu bạn không set file descriptors thì mặc định sẽ là 2000</span> <span class="token keyword">worker_rlimit_nofile</span> <span class="token number">100000</span><span class="token punctuation">;</span> <span class="token comment"># chỉ log những lỗi "chí mạng" (critical) :)))</span> <span class="token keyword">error_log</span> <span class="token operator">/</span>var<span class="token operator">/</span>log<span class="token operator">/</span>nginx<span class="token operator">/</span>error<span class="token punctuation">.</span>log crit<span class="token punctuation">;</span> <span class="token comment"># cung cấp file cấu hình mà trong đó các lệnh ảnh thưởng đến connection processing được chỉ định</span> <span class="token keyword">events</span> <span class="token punctuation">{</span> <span class="token comment"># xác định có bao nhiêu client sẽ được phục vụ mỗi worker</span> <span class="token comment"># max clients = worker_connections * worker_processes</span> <span class="token comment"># max clients cũng bị giới hạn số lượng socket connections có sẵn trên hệ thống (khoảng 64k)</span> <span class="token keyword">worker_connections</span> <span class="token number">4000</span><span class="token punctuation">;</span> <span class="token comment"># tối ưu để phục vụ nhiều client với mỗi thread, cần thiết cho linux (cho môi trường test)</span> <span class="token keyword">use</span> epoll<span class="token punctuation">;</span> <span class="token comment"># accept càng nhiều kết nối càng tốt, có thể flood worker connection nếu set cho nó quá thấp (cho môi trường test)</span> <span class="token keyword">multi_accept</span> on<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">http</span> <span class="token punctuation">{</span> <span class="token comment"># cache thông tin về FDs (file descriptors), files thường xuyên truy cập</span> <span class="token comment"># có thể tăng hiệu suất, nhưng bạn cũng cần test các giá trị này</span> <span class="token keyword">open_file_cache</span> max<span class="token operator">=</span><span class="token number">200000</span> inactive<span class="token operator">=</span><span class="token number">20</span>s<span class="token punctuation">;</span> <span class="token keyword">open_file_cache_valid</span> <span class="token number">30</span>s<span class="token punctuation">;</span> <span class="token keyword">open_file_cache_min_uses</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">open_file_cache_errors</span> on<span class="token punctuation">;</span> <span class="token comment"># để boost I/O trên HDD, chúng ta có thể disable access log</span> <span class="token keyword">access_log</span> off<span class="token punctuation">;</span> <span class="token comment"># sao chép data</span> <span class="token comment"># nhanh hơn đọc + ghi</span> <span class="token keyword">sendfile</span> on<span class="token punctuation">;</span> <span class="token comment"># gửi header trong 1 cục thay vì gửi từng cái</span> <span class="token keyword">tcp_nopush</span> on<span class="token punctuation">;</span> <span class="token comment"># không buffer data sent, tốt cho dữ liệu nhỏ trong thời gian thực</span> <span class="token keyword">tcp_nodelay</span> on<span class="token punctuation">;</span> <span class="token comment"># giảm data cần gửi qua network (cho môi trường test)</span> <span class="token keyword">gzip</span> on<span class="token punctuation">;</span> <span class="token comment"># gzip_static on;</span> <span class="token keyword">gzip_min_length</span> <span class="token number">10240</span><span class="token punctuation">;</span> <span class="token keyword">gzip_comp_level</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">gzip_vary</span> on<span class="token punctuation">;</span> <span class="token keyword">gzip_disable</span> msie6<span class="token punctuation">;</span> <span class="token keyword">gzip_proxied</span> expired no<span class="token operator">-</span>cache no<span class="token operator">-</span>store private <span class="token keyword">auth</span><span class="token punctuation">;</span> <span class="token keyword">gzip_types</span> <span class="token comment"># text/html luôn luôn được nén bởi HttpGzipModule</span> text<span class="token operator">/</span>css text<span class="token operator">/</span>javascript text<span class="token operator">/</span>xml text<span class="token operator">/</span>plain text<span class="token operator">/</span>x<span class="token operator">-</span>component application<span class="token operator">/</span>javascript application<span class="token operator">/</span>x<span class="token operator">-</span>javascript application<span class="token operator">/</span>json application<span class="token operator">/</span>xml application<span class="token operator">/</span>rss<span class="token operator">+</span>xml application<span class="token operator">/</span>atom<span class="token operator">+</span>xml font<span class="token operator">/</span>truetype font<span class="token operator">/</span>opentype application<span class="token operator">/</span>vnd<span class="token punctuation">.</span>ms<span class="token operator">-</span>fontobject image<span class="token operator">/</span>svg<span class="token operator">+</span>xml<span class="token punctuation">;</span> <span class="token comment"># cho phép server đóng connection với client không còn được tương tác, nó sẽ giúp giải phóng bộ nhớ</span> <span class="token keyword">reset_timedout_connection</span> on<span class="token punctuation">;</span> <span class="token comment"># request timed out, mặc định là 60s</span> <span class="token keyword">client_body_timeout</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment"># nếu client ngừng tương tác, giải phóng bộ nhớ, mặc định là 60s</span> <span class="token keyword">send_timeout</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment"># set thời gian server sẽ đóng connection, mặc định là 75s</span> <span class="token keyword">keepalive_timeout</span> <span class="token number">30</span><span class="token punctuation">;</span> <span class="token comment"># số lượng request từ client có thể thực hiện liên tục (cho môi trường test)</span> <span class="token keyword">keepalive_requests</span> <span class="token number">100000</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Sau khi chỉnh sửa xong, bạn cần reload nginx:
1 2 3 | nginx -s reload /etc/init.d/nginx start<span class="token operator">|</span>restart |
Nếu bạn muốn test config thì chạy lệnh sau:
1 2 3 | nginx -t /etc/init.d/nginx configtest |
Chống DDoS
Cách làm này khác xa với secure DDoS nhưng có thể làm chậm một số DDoS nhỏ. Những cấu hình này cũng trong môi trường thử nghiệm và bạn nên tự custom lại cho phù hợp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token comment"># giới hạn số lượng connections với mỗi IP</span> <span class="token keyword">limit_conn_zone</span> <span class="token variable">$binary_remote_addr</span> zone<span class="token operator">=</span>conn_limit_per_ip<span class="token punctuation">:</span><span class="token number">10</span>m<span class="token punctuation">;</span> <span class="token comment"># giới hạn số lượng reqest cho session</span> <span class="token keyword">limit_req_zone</span> <span class="token variable">$binary_remote_addr</span> zone<span class="token operator">=</span>req_limit_per_ip<span class="token punctuation">:</span><span class="token number">10</span>m rate<span class="token operator">=</span><span class="token number">5</span>r<span class="token operator">/</span>s<span class="token punctuation">;</span> <span class="token comment"># nơi mà chúng ta sẽ giới hạn bởi các giá trị trên, ở đây thì mình làm với toàn bộ server</span> <span class="token keyword">server</span> <span class="token punctuation">{</span> <span class="token keyword">limit_conn</span> conn_limit_per_ip <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">limit_req</span> zone<span class="token operator">=</span>req_limit_per_ip burst<span class="token operator">=</span><span class="token number">10</span> nodelay<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment"># nếu như request body size lớn hơn buffer size, thì sau đó toàn bộ (hoặc một phần) request body được ghi vào file tạm</span> <span class="token keyword">client_body_buffer_size</span> <span class="token number">128</span>k<span class="token punctuation">;</span> <span class="token comment"># buffer size cho việc đọc client request header (cho môi trường test)</span> <span class="token keyword">client_header_buffer_size</span> <span class="token number">3</span>m<span class="token punctuation">;</span> <span class="token comment"># số lượng và buffer size tối đa cho các header lớn để đọc từ yêu cầu của client</span> <span class="token keyword">large_client_header_buffers</span> <span class="token number">4</span> <span class="token number">256</span>k<span class="token punctuation">;</span> <span class="token comment"># đặt timeout cho client body (cho môi trường test)</span> <span class="token keyword">client_body_timeout</span> <span class="token number">3</span>m<span class="token punctuation">;</span> <span class="token comment"># đặt thời gian chờ cho client gửi request header (cho môi trương test)</span> <span class="token keyword">client_header_timeout</span> <span class="token number">3</span>m<span class="token punctuation">;</span> |
Test lại config:
1 2 | nginx -t <span class="token comment"># /etc/init.d/nginx configtest</span> |
Nếu mọi thứ ok thì reload hoặc restart nginx:
1 2 3 | nginx -s reload /etc/init.d/nginx reload<span class="token operator">|</span>restart |
Bạn có thể test cấu hình với tsung
và khi bạn thấy ok với kết quả nhậ được, bạn có thể nhấn Ctr + C
(hủy) vì nó có thể chạy nhiều giờ.
Tổng kết
Trên đây là cách tớ đã sử dụng để cài đặt nginx với hiệu suất khá ổn ) hy vọng sẽ giúp ích cho bạn, cảm ơn bạn đã đọc đến đây
Happy coding !!!