服務器模型——從單線程阻塞到多線程非阻塞(上)

前言的前言

服務器模型涉及到線程模式和IO模式,搞清楚這些就能針對各類場景有的放矢。該系列分紅三部分:程序員

  • 單線程/多線程阻塞I/O模型
  • 單線程非阻塞I/O模型
  • 多線程非阻塞I/O模型,Reactor及其改進

前言

這裏探討的服務器模型主要指的是服務器端對I/O的處理模型。從不一樣維度能夠有不一樣的分類,這裏從I/O的阻塞與非阻塞、I/O處理的單線程與多線程角度探討服務器模型。編程

對於I/O,能夠分紅阻塞I/O與非阻塞I/O兩大類型。阻塞I/O在作I/O讀寫操做時會使當前線程進入阻塞狀態,而非阻塞I/O則不進入阻塞狀態。服務器

對於線程,單線程狀況下由一條線程負責全部客戶端鏈接的I/O操做,而多線程狀況下則由若干線程共同處理全部客戶端鏈接的I/O操做。網絡

單線程阻塞I/O模型

單線程阻塞I/O模型是最簡單的一種服務器模型,幾乎全部程序員在剛開始接觸網絡編程時都從這個簡單的模型開始。這種模型只能同時處理一個客戶端訪問,而且在I/O操做上是阻塞的,線程會一直在等待,而不會作其餘事情。對於多個客戶端訪問,必需要等到前一個客戶端訪問結束才能進行下一個訪問的處理,請求一個一個排隊,只提供一問一答服務。多線程

首先,服務器必須初始化一個套接字服務器,並綁定某個端口號並使之監聽客戶端的訪問。接着,客戶端1調用服務器的服務,服務器接收到請求後對其進行處理,處理完後寫數據回客戶端1,整個過程都是在一個線程裏面完成的。最後,處理客戶端2的請求並寫數據回客戶端2,期間就算客戶端2在服務器處理完客戶端1以前就進行請求,也要等服務器對客戶端1響應完後纔會對客戶端2進行響應處理。併發

這種模型的特色在於單線程和阻塞I/O。單線程即服務器端只有一個線程處理客戶端的全部請求,客戶端鏈接與服務器端的處理線程比是n:1,它沒法同時處理多個鏈接,只能串行處理鏈接。而阻塞I/O是指服務器在讀寫數據時是阻塞的,讀取客戶端數據時要等待客戶端發送數據而且把操做系統內核複製到用戶進程中,這時才解除阻塞狀態。寫數據回客戶端時要等待用戶進程將數據寫入內核併發送到客戶端後才解除阻塞狀態。這種阻塞給網絡編程帶來了一個問題,服務器必需要等到客戶端成功接收才能繼續往下處理另一個客戶端的請求,在此期間線程將沒法響應任何客戶端請求。機器學習

該模型的特色:它是最簡單的服務器模型,整個運行過程都只有一個線程,只能支持同時處理一個客戶端的請求(若是有多個客戶端訪問,就必須排隊等待),服務器系統資源消耗較小,但併發能力低,容錯能力差。分佈式

多線程阻塞I/O模型

針對單線程阻塞I/O模型的缺點,咱們可使用多線程對其進行改進,使之能併發地對多個客戶端同時進行響應。多線程模型的核心就是利用多線程機制爲每一個客戶端分配一個線程。服務器端開始監聽客戶端的訪問,假若有兩個客戶端發送請求過來,服務器端在接收到客戶端請求後分別建立兩個線程對它們進行處理,每條線程負責一個客戶端鏈接,直到響應完成。期間兩個線程併發地爲各自對應的客戶端處理請求,包括讀取客戶端數據、處理客戶端數據、寫數據回客戶端等操做。性能

這種模型的I/O操做也是阻塞的,由於每一個線程執行到讀取或寫入操做時都將進入阻塞狀態,直到讀取到客戶端的數據或數據成功寫入客戶端後才解除阻塞狀態。儘管I/O操做阻塞,但這種模式比單線程處理的性能明顯高了,它不用等到第一個請求處理完才處理第二個,而是併發地處理客戶端請求,客戶端鏈接與服務器端處理線程的比例是1:1。學習

多線程阻塞I/O模型的特色:支持對多個客戶端併發響應,處理能力獲得大幅提升,有較大的併發量,但服務器系統資源消耗量較大,並且多線程之間會產生線程切換成本,同時擁有較複雜的結構。

=============廣告時間===============

公衆號的菜單已分爲「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。

鄙人的新書《Tomcat內核設計剖析》已經在京東銷售了,有須要的朋友能夠購買。感謝各位朋友。

爲何寫《Tomcat內核設計剖析》

=========================

歡迎關注:

這裏寫圖片描述
相關文章
相關標籤/搜索