Nginx,uWSGI與Django 應用的關係

前因html

       關於WSGI、uWSGI、uwsgi、Nginx這些名詞及與Django 項目的關係,以前有個善(漂)良(亮)的小姐姐問過我,當時我也不是很明白,沒有給她解釋的很清楚,非常後悔,如今結合網上的一些資料進行一下彙總,且加入了一些我本身的見解,有不足之處還望路過的大佬給予批評指正,拜謝!nginx

名詞介紹web

WSGI (通訊協議)數據庫

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

 

uWSGI(服務器)vim

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

相關文章
相關標籤/搜索