Django(35)Django請求生命周期分析(超詳細)


Django請求生命周期分析


 

1.客戶端發送請求

  1. 在瀏覽器輸入url地址,例如www.baidu.com,瀏覽器會自動補全協議(http),變為http://www.baidu.com,現在部分網站都實現了HSTS機制,服務器自動從http協議重定向到https協議
  2. 在網頁中點擊超鏈接或javascript腳本進行url跳轉,僅設置href='絕對路徑',瀏覽器會自動使用當前url的協議、host和port,例如在https://tieba.baidu.com/index.html網頁中,點擊一個超鏈接/f?kw=chinajoy,會自動訪問https://tieba.baidu.com/f?kw=chinajoy
     

2. 路由轉發

  1. IP查找:因特網內每個公有IP都是唯一的,域名相當於IP的別名,因為我們無法去記住一大堆無意義的IP地址,但如果用一堆有意義的字母組成,大家就能快速訪問對應網站
  2. DNS解析:通過域名去查找IP,先從本地緩存查找,其中本地的hosts文件也綁定了對應IP,若在本機中無法查到,那么就會去請求本地區域的域名服務器(通常是對應的網絡運營商如電信),這個通過網絡設置中的LDNS去查找,如果還是沒有找到的話,那么就去根域名服務器查找,這里有所有因特網上可訪問的域名和IP對應信息(根域名服務器全球共13台)
  3. 路由轉發:通過網卡、路由器、交換機等設備,實現兩個IP地址之間的通信。用到的主要就是路由轉發技術,根據路由表去轉發報文,還有子網掩碼、IP廣播等等知識點
     

3.建立連接

通過TCP協議的三次握手建立連接
 

4.傳輸報文

建立連接后,客戶端會通過TCP依次、有序的發送一定大小的報文,其中包括了超時重傳、阻塞窗口等等概念,用來保證數據包的完整、有序

  • http協議使用的明文傳輸,所有內容都是直接可讀的
  • https協議是基於SSL/TLS加密,而SSL/TLS是基於TCP協議的,也就是http協議報文包裝成TCP報文進行的加密,使用https協議的話,如果本地沒有證書和公鑰,那么會從服務器獲取證書並且進行驗證,流程如下:

     

5.nginx處理

當前django框架開發的web項目,主流使用的服務器架構是:nginx+uWSGI+django
nginx監聽公網IP的某個端口,例如80,接收到請求后,分2種情況處理請求:

  1. 如果是靜態資源(如javascript、css、圖片等)的請求,那么nginx直接獲取到該資源,返回給用戶
  2. 如果是動態內容的請求,那么nginx就將請求轉發到uWSGI,使用的協議一般都是uwsgi,性能最好

注意:

  • 有些reqeust會分多個數據包進行發送,nginx會緩存等待整個request接收完成才調用uWSGI
  • 如果使用的https,那么加密、解密都在nginx中進行處理

 

6.uWSGI處理

uWSGI監聽本機IP的某個端口,例如3308,接收到nginx轉發來的請求后,通過將http協議轉換為WSGI協議,和django程序之間進行通信
 

7.WSGIHandler處理

當django接受到一個請求時,會初始化一個WSGIHandler,可以在項目下的wsgi.py文件進行跟蹤查看:

class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.load_middleware()

    def __call__(self, environ, start_response):
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)
        request = self.request_class(environ)
        response = self.get_response(request)
        
    ......

它接受2個參數:

  • environ:是含有服務器端的環境變量
  • start_response:可調用對象,返回一個可迭代對象。

這個handler控制了從請求到響應的整個過程,首先的就是加載djangosettings配置,然后就是調用django的中間件開始操作
 

8.middleware中間件處理

django操作中間件,首先會調用process_request方法,該方法的作用是處理請求對象,它的參數是request,返回有2種情況

  • response:調用process_response列表處理
  • None:調用下一個中間件的process_request處理

返回response之后的中間件及其業務邏輯都不會處理,直接回返回給瀏覽器
返回None則表示會繼續調用下一個中間件,處理下一個中間件中的邏輯
 
django項目默認有一些自帶的中間件,如下:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

process_request會從上往下依次調用MIDDLEWARE中的中間件,注意:中間件的執行是有順序的,所以我們一般自定義中間件的時候,我們都會將自定義的中間件放到列表最下面

 

9.URLConf路由匹配

通過urls.py文件中的 urlpatterns 配置找到對應的 視圖函數或者視圖類的方法,如果沒有找到匹配的方法,那么就會觸發異常,由中間件的process_exception 進行處理
process_exception:在視圖函數或中間件處理過程拋出異常時調用
參數:

  • request:請求對象
  • exception:是處理過程中拋出的異常對象

返回:

  • response:之后的process_exception都不會觸發,而是調用process_response處理
  • None:調用上一個中間件的process_exception處理

 

10.middleware的process_view

我們通過路由調用視圖之前,會調用中間件的process_view方法進行預處理
process_view:視圖預處理,在視圖函數處理之前調用
參數:

  • view_func:url路由匹配到的視圖函數
  • view_args:視圖函數的可變參數
  • view_kwargs:視圖函數的可變關鍵字參數

返回:

  • response:調用process_response處理
  • None:調用下一個中間件的process_view處理

 

11.views處理request

調用對應的視圖函數或視圖類的方法處理request,例如獲取GETPOST參數,並且調用特定的模型對象執行數據庫操作,如果沒有數據庫操作,那么就直接跳到我們后續的14步了
 

12.models處理

視圖方法中,一般情況下都需要調用模型類進行數據操作,一般是通過模型的manager管理類進行操作的,如:MyModel.objects.get(pk=1)
如果沒有數據操作,那么這一步和下一步就忽略
 

13.數據庫操作

如果django通過模型類執行對數據庫的增刪改查,那么此時整個流程就會在對應的數據庫中執行
 

14.views處理數據

​視圖方法獲取到數據后:

  • 將數據封裝到一個context字典當中,然后調用指定的template.html,通過模板中的變量、標簽和過濾器等,再結合傳入的數據context,會觸發中間件的process_template_response方法,最終渲染成HttpResponse
  • 不調用模板,直接返回數據,譬如 JsonResponseFileResponse
  • 執行redirect,生成一個重定向的HttpResponse,觸發中間件的process_response后,返回到客戶端,結束該web請求的生命周期
     

15.middleware的process_response

調用中間件的 process_response 方法進行處理,最后一個中間件的process_response執行完成后,返回到WSGIHandler類中
 

16.WSGIHandler處理

WSGIHandler類獲取到response后

  • 先處理response的響應行和響應頭,然后調用 start_response 返回http協議的 響應行和響應頭 到uWSGI,這個 start_response 只能調用一次
  • 第一步處理完成后,如果是文件需要對response進行,否則就直接將response作為http協議的body部分返回給uWSGI
     

17.uWSGI處理

uWSGI接收到django程序的返回后,將所有內容包裝成http協議的內容后,通過uwsgi協議返回給nginx服務器處理
 

18.nginx處理

nginx獲取到uWSGI的返回后,將response通過TCP協議返回給客戶端
 

19.客戶端接收響應

客戶端接收到服務器的響應后,做對應的操作,例如:顯示在瀏覽器中,或是javascript的處理等至此,整個web請求的生命周期結束。


免責聲明!

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



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