後端知識體系--一次完整的HTTP請求

來源:互聯網
上載者:User

這裡講的請求是後端DevOps可以控制的範圍內,不包括DNS解析,層層的路由等等,一切都從請求到達我們自己架設的伺服器開始。 1.與伺服器建立串連 1.1 TCP串連的建立

用戶端的請求到達伺服器,首先就是建立TCP串連

Client首先發送一個串連試探,ACK=0 表示確認號無效,SYN = 1 表示這是一個串連請求或串連接受報文,同時表示這個資料報不能攜帶資料,seq = x 表示Client自己的初始序號(seq = 0 就代表這是第0號包),這時候Client進入syn_sent狀態,表示用戶端等待伺服器的回複

Server監聽到串連請求報文後,如同意建立串連,則向Client發送確認。TCP報文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到對方下一個報文段的第一個資料位元組序號是x+1,同時表明x為止的所有資料都已正確收到(ack=1其實是ack=0+1,也就是期望用戶端的第1個包),seq = y 表示Server 自己的初始序號(seq=0就代表這是伺服器這邊發出的第0號包)。這時伺服器進入syn_rcvd,表示伺服器已經收到Client的串連請求,等待client的確認。

Client收到確認後還需再次發送確認,同時攜帶要發送給Server的資料。ACK 置1 表示確認號ack= y + 1 有效(代表期望收到伺服器的第1個包),Client自己的序號seq= x + 1(表示這就是我的第1個包,相對於第0個包來說的),一旦收到Client的確認之後,這個TCP串連就進入Established狀態,就可以發起http請求了。

1.2 常見TCP串連限制

1.2.1 修改使用者進程可開啟檔案數限制

在Linux平台上,無論編寫用戶端程式還是服務端程式,在進行高並發TCP串連處理時,最高的並發數量都要受到系統對使用者單一進程同時可開啟檔案數量的限制(這是因為系統為每個TCP串連都要建立一個socket控制代碼,每個socket控制代碼同時也是一個檔案控制代碼)。可使用ulimit命令查看系統允許目前使用者進程開啟的檔案數限制,windows上是256,linux是1024,這個部落格的伺服器是65535

1.2.2 修改網路核心對TCP串連的有關限制

在Linux上編寫支援高並發TCP串連的用戶端通訊處理常式時,有時會發現儘管已經解除了系統對使用者同時開啟檔案數的限制,但仍會出現並發TCP串連數增加到一定數量時,再也無法成功建立新的TCP串連的現象。出現這種現在的原因有多種。
第一種原因可能是因為Linux網路核心對本地連接埠號碼範圍有限制。此時,進一步分析為什麼無法建立TCP串連,會發現問題出在connect()調用返回失敗,查看系統錯誤提示訊息是“Can’t assign requestedaddress”。同時,如果在此時用tcpdump工具監視網路,會發現根本沒有TCP串連時用戶端發SYN包的網路流量。這些情況說明問題在於本地Linux系統核心中有限制。

其實,問題的根本原因在於Linux核心的TCP/IP協議實現模組對系統中所有的用戶端TCP串連對應的本地連接埠號碼的範圍進行了限制(例如,核心限制本地連接埠號碼的範圍為1024~32768之間)。當系統中某一時刻同時存在太多的TCP用戶端串連時,由於每個TCP用戶端串連都要佔用一個唯一的本地連接埠號碼(此連接埠號碼在系統的本地連接埠號碼範圍限制中),如果現有的TCP用戶端串連已將所有的本地連接埠號碼佔滿,則此時就無法為新的TCP用戶端串連分配一個本地連接埠號碼了,因此系統會在這種情況下在connect()調用中返回失敗,並將錯誤提示訊息設為“Can’t assignrequested address”。 2.發起HTTP請求

2.1 請求格式

例如這樣的一個請求

Accept 就是告訴伺服器端,我接受那些MIME類型

Accept-Encoding 這個看起來是接受那些壓縮方式的檔案

Accept-Lanague 告訴伺服器能夠發送哪些語言

Connection 告訴伺服器支援keep-alive特性

Cookie 每次請求時都會攜帶上Cookie以方便伺服器端識別是否是同一個用戶端

Host 用來標識請求伺服器上的那個虛擬機器主機,比如Nginx裡面可以定義很多個虛擬機器主機
那這裡就是用來標識要訪問那個虛擬機器主機。

User-Agent 使用者代理程式,一般情況是瀏覽器,也有其他類型,如:wget curl 搜尋引擎的蜘蛛等

條件請求首部:
If-Modified-Since 是瀏覽器向伺服器端詢問某個資源檔如果自從什麼時間修改過,那麼重新發給我,這樣就保證伺服器端資源
檔案更新時,瀏覽器再次去請求,而不是使用緩衝中的檔案

安全請求首部:
Authorization: 用戶端提供給伺服器的認證資訊

2.2 keep-alive/persitent

每次HTTP請求都重建立立TCP串連的開銷是很大的,於是就出現了keep-alive這個首部,它允許在一次TCP串連中發送/接收多個HTTP報文

然而,keep-alive是有弊端的。在HTTP1.0中,用戶端發起請求是加上keep-alive首部,服務端響應時也加上keep-alive首部,那麼這個請求就被認為是keep-alive的,直到其中一方主動斷開為止。如果沒有正確斷開,這個資源就會一直被佔用了。

啞代理問題:啞代理只是單純的轉寄請求,並不能進行解析處理、維持持久串連等其他工作,而聰明的代理可以解析接收到的報文同時可以維持持久串連。

 如上圖,當用戶端與伺服器之間存在不解析直接轉寄的代理時,connection:keep-alive這個首部是直接轉寄給伺服器的,伺服器接收了這個請求之後,就會向用戶端發送帶有connection:keep-alive的響應,同樣盲代理不會解析響應,直接將全部響應轉寄回用戶端。因為用戶端收到了這個首部,就認為建立持久串連已經成功了,但是中間的”笨代理“,並不知道這些事情,笨代理只有一種行為模式:在轉寄請求和回送伺服器響應請求之後就認為這次事務結束了,等待串連斷開,而這時由於connection:keep-alive首部已經發送到伺服器和用戶端,雙方都認為持久串連已經建立完成,這樣就變成了兩邊認為持久串連OK而中間的啞代理等待串連斷開的情況,這種情況下如果用戶端再一次在這條串連上發送請求,請求就會在亞代理處停止,因為啞代理已經在等待串連關閉。這種狀態會導致瀏覽器一直處於掛起狀態,直到用戶端或伺服器之中一個連線逾時,關閉串連為止,一段美好的牽手就這麼沒了(啞代理就是把內容原封不動的轉寄到代理)。為了避免這種情況,現代的代理是不會轉寄connection:keep-alive這個首部的。

persistent

HTTP/1.1的持久串連預設是開啟的,只有首部中包含connection:close,才會事務結束之後關閉串連。當然伺服器和用戶端仍可以隨時關閉持久串連。

當發送了connection:close首部之後用戶端就沒有辦法在那條串連上發送更多的請求了。當然根據持久串連的特性,一定要傳輸正確的content-length。

還有根據HTTP/1.1的特性,是不應該和HTTP/1.0用戶端建立持久串連的。最後,一定要做好重發的準備。

管道化串連

HTTP/1.1允許在持久串連上使用管道,這樣就不用等待前一個請求的響應,直接在管道上發送第二個請求,在高延遲下,提高效能。

管道化串連的限制: 不是持久串連就不能使用管道。 必須按照同樣的發送順序回送響應,因為報文沒有標籤,很可能就順序就亂咯。 因為可以隨時關閉持久串連,所以要隨時做好重發準備 不應該使用管道化發送重複發送會有副作用的請求(如post,重複提交)。 3.負載平衡

接收到HTTP請求之後,就輪到負載平衡登場了,它位於網站的最前端,把短時間內較高的訪問量分攤到不同機器上處理。負載平衡方案有軟體、硬體兩種

F5 BIG-IP是著名的硬體方案,但這裡不作討論

軟體方案有LVS HAProxy Nginx等,留作以後補充 4.Nginx(WEB伺服器)

在典型的Rails應用部署方案中,Nginx的作用有兩個 處理靜態檔案請求 轉寄請求給後端的Rails應用

這是一個簡單的Nginx設定檔

後端的Rails伺服器通過unix socket與Nginx通訊,Nginx伺服public檔案夾裡的靜態檔案給使用者 5.Rails(應用伺服器)

這篇文章無敵了,我沒有更多可以寫的,只能說一句我用的是Puma。因為伺服器是單核的,只能用多線程Puma或者事件驅動的Thin,考慮到以後可能用上Rails 5 ActionCabel,還是直接上Puma吧。 6.資料庫(資料庫伺服器)

應用伺服器想訪問資料庫,就需要與資料庫建立串連。Rails讀取database.yml中的配置,訪問對應的資料庫。

一個重要的配置指標pool: Rails中的資料庫連接是完全安全執行緒的,所有pool的值要配置成與Puma的最大線程數相等,這樣就不會出現線程等待資料庫連接的情況。 7.Redis、Memercache(快取服務器) 8.訊息佇列 9.搜尋 參考文獻

一次完整的HTTP事務是怎樣一個過程。

Linux下高並發socket最大串連數所受的各種限制

Keep-Alive

談談持久串連——HTTP權威指南讀書心得(五)

資料庫連接池的工作原理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.