前面我們在章節“Socket通訊探索(一)”中如何實現一個tcp連接,但是這僅僅是一個最初級的BIO實現,且沒有添加線程池,實際應用中很少採用這種方式,因為不得不考慮當大量的Tcp連接建立的時候,服務端如何安全穩定的運行?為什麼呢? 1、BIO實現方式,是阻塞式的(上一節最後面的實現方式雖然無數據的 ...
前面我們在章節“Socket通訊探索(一)”中如何實現一個tcp連接,但是這僅僅是一個最初級的BIO實現,且沒有添加線程池,實際應用中很少採用這種方式,因為不得不考慮當大量的Tcp連接建立的時候,服務端如何安全穩定的運行?為什麼呢?
1、BIO實現方式,是阻塞式的(上一節最後面的實現方式雖然無數據的時候,不會阻塞);
2、服務端為每條連接都開闢了一個線程進行處理,而且在連接不斷開的情況下,線程不會得到釋放;
基於以上情況,當有大量的連接建立的時候,服務端會開闢大量的線程處理並得不到釋放,而線程會占用系統資源,這樣就會導致系統資源耗盡,沒有系統資源的連接請求將會等待處理,更甚至程式直接崩潰,所以最直接的方式是添加線程池防止程式崩潰,大量的連接的處理則還還需要另想他法。
大家都知道當web應用面臨大量的請求時,我們會對其進行集群或分散式等方式部署,同理,我們也可以對socket服務端進行多處部署。
通常,由於Tcp連接中客戶端需要知道服務端的IP跟埠,那麼這就意味著客戶端需要知道所有的目標伺服器的地址和埠,如果有那麼一臺主機專門用於對我們的伺服器進行負載均衡,然後將負載均衡完成後選擇的地址跟埠返回給客戶端,然後客戶端再發起真實的連接請求。具體的請求過程如下圖(詳細請參考:https://wenku.baidu.com/view/d5769f85d4d8d15abe234e7c):
以上圖中的virtual server實際上就是一個負載均衡用的伺服器,所有客戶端都會優先連接此伺服器得到真實伺服器連接(real server);該模型具體的通信流程如下:
①client向處於偵聽的vs發SYN包;
②VS按照調度策略選擇一個RS,並向RS發SYN包;
④RS響應VS的SYN請求,將SYN ACK包返回給VS;
④VS將收到的SYN ACK包發給client;
④client將5次握手的最後一個ACK包直接發給RS,此時client進入已建立連接狀態,RS在收到ACK包後也進入已建立連接狀態
⑥client和RS直接通信,此過程與VS無關。
通過以上模型即可完成TCP服務端集群部署,至於具體的實現過程,不在本篇的範疇之內,就目前來說,我只瞭解這一種實現方式,如果還有其他的方案,大家可以相互交流……