2011-01-21 17 views
16

Tôi đang cố hiểu điều gì khiến Nginx quá nhanh và tôi có một vài câu hỏi.nginx: Đa luồng của nó nhưng sử dụng nhiều quy trình?

Như tôi đã hiểu, Apache hoặc sinh ra một quy trình mới để phục vụ mỗi yêu cầu HOẶC sinh ra một luồng mới để phục vụ cho mỗi yêu cầu. Vì mỗi chuỗi mới chia sẻ không gian địa chỉ ảo nên việc sử dụng bộ nhớ sẽ tăng lên nếu có một số yêu cầu đồng thời sắp tới.

Nginx giải quyết điều này bằng cách chỉ thực hiện một quy trình nghe (Master), với một chuỗi thực hiện đơn VÀ 2 hoặc 3 (số là cấu hình) quy trình công nhân. Quy trình/luồng chính này đang chạy vòng lặp sự kiện. Có hiệu lực chờ đợi cho bất kỳ yêu cầu đến. Khi một yêu cầu đến trong nó đưa ra yêu cầu đó cho một trong các quy trình công nhân.

Xin vui lòng sửa tôi nếu hiểu biết ở trên của tôi là không đúng

Nếu ở trên là chính xác, sau đó tôi có một vài câu hỏi:

1.) Không phải là quá trình lao động sẽ đẻ trứng nhiều chủ đề và sẽ chạy vào cùng một vấn đề như apache?

2.) Hoặc là nginx nhanh vì kiến ​​trúc dựa trên sự kiện của nó sử dụng nonblocking-IO bên dưới tất cả. Có lẽ quy trình công nhân sinh ra các chủ đề làm chỉ không chặn-IO, phải không?

3.) "Chính xác" là "kiến trúc dựa trên sự kiện" nào, ai đó có thể thực sự đơn giản hóa nó, cho những người như tôi hiểu. Liệu nó chỉ liên quan đến non-blocking-io hay cái gì khác nữa?

Tôi có một tham chiếu đến c10k, tôi đang cố gắng trải qua nó, nhưng tôi không nghĩ về kiến ​​trúc dựa trên sự kiện của nó. nó có vẻ nhiều hơn cho nonblocking IO.

+0

IO không yêu cầu kiến ​​trúc dựa trên sự kiện. –

+0

FYI - Chỉ trong trường hợp bạn quan tâm đến việc đào sâu hơn - Tôi đã viết câu trả lời cùng với các tài liệu khác + video trên đây: http://planetunknown.blogspot.com/2011/02/why-nginx-is-faster- than-apache.html – PlanetUnknown

Trả lời

17

Nó không phải là rất phức tạp từ một quan điểm khái niệm. Tôi sẽ cố gắng rõ ràng nhưng tôi phải làm một số đơn giản hóa.

Máy chủ dựa trên sự kiện (như nginxlighttpd) sử dụng trình bao bọc xung quanh hệ thống theo dõi sự kiện. Ví dụ. lighttpd sử dụng libevent để trừu tượng hệ thống giám sát sự kiện tốc độ cao nâng cao hơn (xem libev cũng).

Máy chủ theo dõi tất cả các kết nối không chặn mà nó có (cả văn bản và đọc) sử dụng một máy trạng thái đơn giản cho từng kết nối. Hệ thống giám sát sự kiện thông báo cho quá trình máy chủ khi có dữ liệu mới hoặc khi có thể ghi thêm dữ liệu. Nó giống như một select() trên steroid, nếu bạn biết lập trình socket. Quá trình máy chủ sau đó chỉ cần gửi tệp được yêu cầu bằng cách sử dụng một số chức năng nâng cao như sendfile() nếu có thể hoặc chuyển yêu cầu sang quy trình CGI bằng cách sử dụng ổ cắm để liên lạc (ổ cắm này sẽ được giám sát với hệ thống giám sát sự kiện như các kết nối mạng khác.)

This liên kết với rất nhiều thông tin tuyệt vời về nội bộ của nginx, chỉ trong trường hợp. Tôi hy vọng nó sẽ giúp.

+0

Cảm ơn Ass3mbler. Tôi nghĩ điều đó đã giúp ích trong việc hiểu nó. – PlanetUnknown

+0

@PlanetUnknow Tôi thực sự vui vì nó đã giúp ích. Nếu bạn cần thêm thông tin, chỉ cần hỏi tôi, tôi đã làm việc nhiều lần để sửa đổi nguồn của lighttpd. Nếu nó là ok bạn có thể chấp nhận câu trả lời của tôi xin vui lòng? Cảm ơn bạn! – Ass3mbler

+0

Cảm ơn Ass3mbler. Tôi nghĩ điều đó đã giúp ích trong việc hiểu nó. Vì vậy, quá trình tổng thể là lắng nghe lưu lượng truy cập đến và các quy trình công nhân đang chạy vòng lặp sự kiện (đăng ký các sự kiện và phản hồi khi xảy ra). Tóm lại, điều đó có đúng không? – PlanetUnknown

46

Apache sử dụng nhiều luồng để cung cấp cho mỗi yêu cầu có chuỗi thực thi riêng của nó. Điều này là cần thiết để tránh bị chặn khi sử dụng I/O đồng bộ.

Nginx chỉ sử dụng I/O không đồng bộ, làm cho việc chặn không thành vấn đề. Lý do duy nhất nginx sử dụng nhiều quy trình, là tận dụng tối đa các hệ thống đa lõi, đa CPU và siêu phân luồng. Ngay cả với hỗ trợ SMP, hạt nhân không thể lên lịch một luồng thực thi đơn lẻ trên nhiều CPU.Nó đòi hỏi ít nhất một quy trình hoặc luồng cho mỗi CPU logic.

Vì vậy, sự khác biệt là, nginx đòi hỏi chỉ đủ quá trình lao động để có được những lợi ích đầy đủ của SMP, trong khi kiến ​​trúc của Apache đòi hỏi tạo một chủ đề mới (mỗi ngăn xếp riêng của nó khoảng ~ 8MB) theo yêu cầu. Rõ ràng, ở mức độ tương tranh cao, Apache sẽ sử dụng nhiều bộ nhớ hơn và chịu chi phí cao hơn từ việc duy trì số lượng lớn các luồng.

+3

câu trả lời rất rõ ràng! – clime

+0

Tại sao không sử dụng nhiều luồng để tận dụng CPU đa nhân? – spockwang

+0

@spockwang Thật vậy, họ sử dụng một công nhân cho lõi. _ ** Cấu hình NGINX được khuyến nghị trong hầu hết các trường hợp - chạy một quy trình công nhân trên mỗi lõi CPU - làm cho việc sử dụng tài nguyên phần cứng hiệu quả nhất. ** _ từ [NGINX docs] (https://www.nginx.com/blog/inside -nginx-how-we-design-for-performance-scale) – gabrielgiussi

6

Apache không sinh ra một chuỗi mới cho mỗi yêu cầu. Nó duy trì một bộ nhớ cache của chủ đề hoặc một nhóm các quá trình trước khi chia hai mà nó trang trại ra yêu cầu. Số lượng yêu cầu đồng thời bị giới hạn bởi số lượng con/chủ đề có, nhưng apache không sinh ra một luồng/con mới cho mọi yêu cầu sẽ chậm chạp (ngay cả với chủ đề, tạo và teardown cho mọi yêu cầu sẽ là quá chậm)

Nginx sử dụng mô hình công nhân chính. Quy trình tổng thể đề cập đến việc tải cấu hình và tạo/hủy/duy trì công nhân. Giống như apache, nó bắt đầu với một số các quy trình đã được phân nhánh trước đã chạy mỗi trong số đó là một công nhân (và một trong số đó là quy trình "chính"). MACHI quy trình công nhân chia sẻ một bộ các ổ cắm nghe. Mỗi quy trình công nhân chấp nhận các kết nối và xử lý chúng, nhưng mỗi nhân viên có thể xử lý các kết nối cùng một lúc, không giống như apache mà chỉ có thể xử lý 1 kết nối cho mỗi nhân viên.

Cách nginx đạt được điều này là thông qua "ghép kênh". Nó không sử dụng libevent, nó sử dụng một vòng lặp sự kiện tùy chỉnh được thiết kế đặc biệt cho nginx và phát triển với sự phát triển của phần mềm nginx. Multiplexing hoạt động bằng cách sử dụng một vòng lặp để "increment" thông qua một chương trình chunk bởi đoạn hoạt động trên một phần của dữ liệu/kết nối mới/bất cứ điều gì cho mỗi kết nối/đối tượng mỗi vòng lặp lặp đi lặp lại. Tất cả đều dựa trên các backend như Epoll() kqueue() và select(). Bạn nên đọc số nào trên

Các vấn đề liên quan