WSGI 協議
WSGI:是一種協議規範,起到規範參數的做用,就像告訴公路同樣,規定超車靠右行,速度不低於90km/h,等。但這一切都是對雙方進行溝通,好比,重慶到武漢這條高速路,這兒重慶和武漢就各爲一端,他們之間的行車規範就按照WSGI規則便可。咱們如今須要記住,WSGI溝通的雙方是wsgi server (好比uWSGI) 要和 wsgi application(好比django )php
wsgi server (好比uWSGI)實現wsgi協議規範的服務器咱們叫作wsgi服務器,也就是uWSGI服務器,
wsgi application(好比django )實現wsgi協議的應用,咱們叫作wsgi應用,好比Django,Falskjava
uWSGI
uWGSI:是一個web服務器,或者wsgi server服務器,他的任務就是接受用戶請求,因爲用戶請求是經過網絡發過來的,其中用戶到服務器端之間用的是http協議,因此咱們uWSGI要想接受而且正確解出相關信息,咱們就須要uWSGI實現http協議,沒錯,uWSGI裏面就實現了http協議。因此如今咱們uWSGI能準確接受到用戶請求,而且讀出信息。如今咱們的uWSGI服務器須要把信息發給Django,咱們就須要用到WSGI協議,恰好uWSGI實現了WSGI協議,因此。uWSGI把接收到的信息做一次簡單封裝傳遞給Django,Django接收到信息後,再通過一層層的中間件,因而,對信息做進一步處理,最後匹配url,傳遞給相應的視圖函數,視圖函數作邏輯處理......後面的就不敘述了,而後將處理後的數據經過中間件一層層返回,到達Djagno最外層,而後,經過WSGI協議將返回數據返回給uWSGI服務器,uWSGI服務器經過http協議將數據傳遞給用戶。這就是整個流程。python
這個過程當中咱們彷佛沒有用到uwsgi協議,可是他也是uWSGI實現的一種協議,魯迅說過,存在即合理,因此說,他確定在某個地方用到了。咱們過一會再來討論nginx
咱們能夠用這條命令:python manage.py runserver,啓動Django自帶的服務器,具體叫什麼名字,我真不知道(知道的能夠留言)。DJango自帶的服務器(runserver 起來的 HTTPServer 就是 Python 自帶的 simple_server)。是默認是單進程單多線程的,對於同一個http請求,老是先執行一個,其餘等待,一個一個串行執行。沒法並行。並且django自帶的web服務器性能也很差,只能在開發過程當中使用。因而咱們就用uWSGI代替了。可是uWSGI也不夠好,爲何看下圖。web
爲何有了uWSGI爲何還須要nginx?
由於nginx具有優秀的靜態內容處理能力,而後將動態內容轉發給uWSGI服務器,這樣能夠達到很好的客戶端響應。支持的併發量更高,方便管理多進程,發揮多核的優點,提高性能。這時候nginx和uWSGI之間的溝通就要用到uwsgi協議。django
雜談
django 的併發能力真的是使人擔心,這裏就使用 nginx + uwsgi 提供高併發tomcat
nginx 的併發能力超高,單臺併發能力過萬(這個也不是絕對),在純靜態的 web 服務中更是突出其優越的地方,因爲其底層使用 epoll 異步IO模型進行處理,使其深受歡迎服務器
作過運維的應該都知道,網絡
Python須要使用nginx + uWSGI 提供靜態頁面訪問,和高併發多線程
php 須要使用 nginx + fastcgi 提供高併發,
java 須要使用 nginx + tomcat 提供 web 服務
django 原生爲單線程序,當第一個請求沒有完成時,第二個請求輝阻塞,知道第一個請求完成,第二個請求才會執行。 Django就沒有用異步,經過線程來實現併發,這也是WSGI廣泛的作法,跟tornado不是一個概念 官方文檔解釋django自帶的server默認是多線程 django開兩個接口,第一個接口sleep(20),另外一個接口不作延時處理(大概耗時幾毫秒) 先請求第一個接口,緊接着請求第二個接口,第二個接口返回數據,第一個接口20秒以後返回數據 證實django的server是默認多線程 啓動uWSGI服務器 # 在django項目目錄下 Demo工程名 uwsgi --http 0.0.0.0:8000 --file Demo/wsgi.py
通過上述的步驟測試,發如今這種狀況下啓動django項目,uWSGI也是單線程,訪問接口須要"排隊" 不給uWSGI加進程,uWSGI默認是單進程單線程 uwsgi --http 0.0.0.0:8000 --file Demo/wsgi.py --processes 4 --threads 2 # processes: 進程數 # processes 和 workers 同樣的效果 # threads : 每一個進程開的線程數
通過測試,接口能夠"同時"訪問,uWSGI提供多線程
- Python由於GIL的存在,在一個進程中,只容許一個線程工做,致使單進程多線程沒法利用多核
- 多進程的線程之間不存在搶GIL的狀況,每一個進程有一個本身的線程鎖,多進程多GIL