Nginx,uWSGI與Django 應用的關系


前因

       關於WSGI、uWSGI、uwsgi、Nginx這些名詞及與Django 項目的關系,之前有個善(漂)良(亮)的小姐姐問過我,當時我也不是很明白,沒有給她解釋的很清楚,很是后悔,現在結合網上的一些資料進行一下匯總,且加入了一些我自己的看法,有不足之處還望路過的大佬給予批評指正,拜謝!

名詞介紹

WSGI (通信協議)

全稱Web Server Gateway Interface(Web服務器網關接口),它不是服務器、Python模塊、框架、API或者任何軟件,只是一種描述Web 服務器(如nginx,uWSGI 等服務器)如何與Web 應用程序(如用Django、Flask框架寫的程序)通信的規范,是一種實現了比如Python 解析的通用接口標准/標准,實現了Python Web 程序與服務器交互的通用性,利用這個協議,Web 項目就可以輕松部署在不同的Web Server 上了。

 

uWSGI(服務器)

uWSGI 是一個全功能的HTTP 服務器,實現了WSGI 協議、uwsgi協議、http協議等,它要做的就是把HTTP協議轉化成語言支持的網絡協議,比如把HTTP協議轉換成WSGI 協議,讓Python 可以直接使用。

 

uwsgi(線路協議)

與WSGI 一樣,是uWSGI服務器的獨占通信協議,用於定義傳輸信息的類型(type of information)。每一個uwsgi packet 前4 byte 為傳輸信息類型的描述,與WSGI 協議是兩種東西,據說該協議是fcgi協議的10倍快。

 

Nginx

Nginx 是一個開源的高性能的HTTP 服務器和反向代理,具體作用:
1.可以作為web 服務器,處理靜態文件和索引文件效率非常高;
2.它的設計非常注重效率,最大支持5萬個並發連接,但是只占用很少的內存空間;
3.穩定性高,配置簡潔;
4.還可以用於強大的反向代理和負載均衡功能,平衡集群中各個服務器的負載壓力應用。

很多資料上都有的一句話,交代了這幾個名詞的關系:uWSGI 服務器實現了WSGI協議,uwsgi協議,http協議等等,Nginx 中的HttpUwsgiModule 的作用是與uWSGI 服務器進行交換。

 

以Django 框架開發為例

Django

Django 是一個Web框架,框架的作用在於處理request 和response,其他的不是框架所關心的內容,所以如何部署Django 也不是Django 所需要關心的。
Django 所提供的是一個開發服務器,這個開發服務器,沒有經過安全測試,而且使用的是Python 自帶的simple HTTPServer 創建的,如果你看了Django 源碼就知道,runserver 起來的HTTPServer 就是Python 自帶的simple HTTPServer,所以在安全性和效率上都是不行的。

在Django 開發的Web 應用程序中,nginx和uWSGI 服務器之間是如何配合工作的?

 

1.首先客戶端發送http 請求,來獲取服務器資源;
2.Nginx 作為直接對外的服務器接口,接收到客戶端發過來的http請求,然后進行解包、分析;
3.如果是靜態資源的請求,會根據nginx 配置的靜態文件目錄,返回請求的資源;
4.如果是動態資源的請求,nginx 就會通過配置,將請求傳遞給uWSGI 服務器;
5.uWSGI 將接收到的數據包進行處理,並轉發給WSGI(HTTP 協議轉成WSGI 協議);
6.WSGI 根據請求調用Django 項目中的某個文件或函數,進行邏輯處理,完成后Django 將返回值交給WSGI;
7.WSGI 將返回值打包,轉發給uWSGI 服務器(WSGI 協議轉換成HTTP 協議);
8.uWSGI 服務器接收后轉發給Nginx 服務器,最終Nginx 服務器將返回值返回給客戶端(如瀏覽器)
注意:不同的組件之間傳遞信息涉及到數據格式和協議的轉換

 

關於Nginx

1.第一級的Nginx 並不是必須的,uwsgi 完全可以完成整個和瀏覽器交互的流程;
2.在Nginx 上加上安全性或其他得限制,可以達到保護程序的作用;
3.uWSGI 本身是內網接口,開啟多個work 和processes 可能也不夠用,而Nginx 可以代理多台uWSGI 完成uWSGI 負載均衡;
4.Django 在Debug=Flase 下對靜態文件的處理能力不是很好,而用Nginx 來處理會更加高效

 

       一個成熟的站點提供服務,需要Web 服務器(靜態數據)和APP 服務器(動態數據)。Web 服務器目前屬Nginx 最強大,用戶請求代理過來后,把靜態數據返回給客戶端。但是目前的互聯網發展時代,都是包含動態數據處理的,Nginx 不處理業務邏輯,都外包給后端的APP 服務器,比如Django 框架開發的服務器。

       再需要性能優化的場景,單單通過Nginx 和uWSGI 也是不夠的,Nginx 主要的優化是連接數和處理靜態資源的請求,uWSGI 主要優化的是WSGI 服務,這些都只是手段,其他手段包括:優化數據庫、增加緩存、加入負載均衡、引入異步IO 框架(如gunicorn 服務器的gevent 框架)、計算密集型模塊用C 重寫等。安全性方面,也有很多考慮,原作者沒有展開介紹:)

 

擴展

下面是我之前截圖的一個大佬自己測試的各種配置的性能對比,原帖暫時找不到,如果大佬看見了,請在下面留言,我會根據您的要求,添加或刪除這部分資料,謝謝


1.Django

毫無疑問,用原生Django 的Server 做處理的表現是最爛的(上面介紹了,Django 原生的Server 就是Python 自帶的simple HTTPServer 創建的),在10000 次請求的情況下,broken pipe (就是請求失敗吧)的幾率極高,只有1400次請求被處理,成功了只有14%,原作者懶得繼續測下去了(以后有機會我也測試測試)。


2.Django + Nginx

這次搭上了Nginx 做反向代理,也使得脆弱的Django 服務器的情況有所緩解,但成功率仍然不高(10000 次請求中有3684 個請求被處理)。


3.uWSGI + Nginx

uWSGI 是性能極高的一個由C 編寫的服務器,使用了自身獨占的uwsgi 協議,這次讓它配合Nginx 處理Django 的request,參數為4 進程 + 2 線程,性能立即直線商城,處理請求的成功率也基本在90% 左右,原作者在測試的時候遇到了一個坑,就是uWSGI 在處理請求的時候發送了隊列溢出的問題,因為當前測試設置的並發數為每秒1000 次並發,而uWSGI 的處理隊列的容量默認是100*(啟動的uWSGI 的進程數),導致處理請求的時間加長,而這個問題則可以通過修改somaxcon 的大小解決(具體做法在5 個配置下面 ),總的來說,使用uWSGI + Nginx 是一個理想的選擇。


4.Gunicorn + Nginx

gunicorn 跟 uWSGI 類似,也是一個高性能的http 服務器,它由ruby 的unicorn 項目移植,是由Python 編寫的,它的配置簡單,而且可以靈活的搭配其他網絡庫,部署十分方便,在測試數據中可以看到,用這種配置運行Django 能在短時間內就能處理大量的並發請求,成功率在90% 左右。
(我們之前這種配置都是配置Flask 框架開發的Web 服務器)


5.Gunicorn + Nginx +Gevent

前面說的幾種環境,看似不錯,但是作者說了,我們需要追求完美!由於gunicorn 是同步(sync)單線程模型的,有時候不免會發生一些阻塞問題,這時候我們為gunicorn 加上 -k gevent 參數來用gevent 做處理接口,這就比較靠譜的處理了阻塞問題,從作者的測試結果可以得到,這種模式下不僅擁有100% 的處理成功率,而且時間也在很短之內完成,是5組測試數據當中性能最好的!
補充一句:原作者好棒!

 

uWSGI listen queue 隊列溢出的修補措施:

1.修改系統參數
vim /etc/sysctl.conf
在文件最后添加一行記錄net.core.somaxcon = 1024
執行sysctl -p重新load參數設置,這樣會立即生效,並且以后重新啟動機器也會生效。

2.設置uwsgi啟動的--listen 1024.
這樣 你的機器並發數就可以得到一個很大的提升。

 

參考:

1.百度百科

2.uWSGI + django + nginx 的工作原理流程與部署歷程:https://blog.csdn.net/c465869935/article/details/53242126

3.uWSGI listen queue 隊列溢出的問題:http://www.cnblogs.com/zhujie/archive/2012/04/27/2474051.html

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM