Quá đơn giản: Bạn cần một cái gì đó thực thi Python nhưng Python không phải là tốt nhất để xử lý tất cả các loại yêu cầu.
[từ chối trách nhiệm: Tôi là nhà phát triển Gunicorn]
Ít đơn giản hơn: Bất kể máy chủ ứng dụng nào bạn sử dụng (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy), bất kỳ loại triển khai không tầm thường nào cũng sẽ có thứ gì đó ngược dòng sẽ xử lý các yêu cầu mà ứng dụng Django của bạn không nên xử lý. Các ví dụ tầm thường của các yêu cầu như vậy đang phục vụ các tài sản tĩnh (hình ảnh / css / js).
Điều này dẫn đến hai tầng đầu tiên của "kiến trúc ba tầng" cổ điển. Tức là, máy chủ web (Nginx trong trường hợp của bạn) sẽ xử lý nhiều yêu cầu cho hình ảnh và tài nguyên tĩnh. Các yêu cầu cần được tạo động sau đó sẽ được chuyển đến máy chủ ứng dụng (Gunicorn trong ví dụ của bạn). (Như một bên, thứ ba trong ba tầng là cơ sở dữ liệu)
Về mặt lịch sử, mỗi tầng này sẽ được lưu trữ trên các máy riêng biệt (và rất có thể sẽ có nhiều máy trong hai tầng đầu tiên, tức là: 5 máy chủ web gửi yêu cầu đến hai máy chủ ứng dụng lần lượt truy vấn một cơ sở dữ liệu).
Trong thời kỳ hiện đại, chúng ta có các ứng dụng của tất cả các hình dạng và kích cỡ. Không phải mọi dự án cuối tuần hoặc trang web kinh doanh nhỏ thực sự cần mã lực của nhiều máy và sẽ chạy khá vui vẻ trên một hộp. Điều này đã sinh ra các mục mới vào mảng các giải pháp lưu trữ. Một số giải pháp sẽ kết hôn máy chủ ứng dụng với máy chủ web (Apache httpd + mod_wsgi, Nginx + mod_uwsgi, v.v.). Và không có gì lạ khi lưu trữ cơ sở dữ liệu trên cùng một máy như một trong những kết hợp máy chủ web / ứng dụng này.
Bây giờ trong trường hợp của Gunicorn, chúng tôi đã đưa ra một quyết định cụ thể (sao chép từ Kỳ lân của Ruby) để giữ mọi thứ tách biệt với Nginx trong khi dựa vào hành vi ủy quyền của Nginx. Cụ thể, nếu chúng ta có thể cho rằng Gunicorn sẽ không bao giờ đọc các kết nối trực tiếp từ internet, thì chúng ta không phải lo lắng về các khách hàng chậm. Điều này có nghĩa là mô hình xử lý cho Gunicorn rất đơn giản.
Việc phân tách cũng cho phép Gunicorn được viết bằng Python thuần giúp giảm thiểu chi phí phát triển trong khi không ảnh hưởng đáng kể đến hiệu suất. Nó cũng cho phép người dùng khả năng sử dụng các proxy khác (giả sử họ đệm chính xác).
Đối với câu hỏi thứ hai của bạn về những gì thực sự xử lý yêu cầu HTTP, câu trả lời đơn giản là Gunicorn. Câu trả lời đầy đủ là cả Nginx và Gunicorn đều xử lý yêu cầu. Về cơ bản, Nginx sẽ nhận được yêu cầu và nếu đó là một yêu cầu động (thường dựa trên các mẫu URL) thì nó sẽ gửi yêu cầu đó cho Gunicorn, sẽ xử lý nó và sau đó trả lại phản hồi cho Nginx, sau đó chuyển phản hồi trở lại ban đầu khách hàng
Vì vậy, trong đóng cửa, có. Bạn cần cả Nginx và Gunicorn (hoặc một cái gì đó tương tự) để triển khai Django thích hợp. Nếu bạn đặc biệt muốn tổ chức Django với Nginx, thì tôi sẽ điều tra Gunicorn, mod_uwsgi và có thể CherryPy là ứng cử viên cho phe Django.