Linux TCP實現優化的背後想法

想象一下當初爲何不讓多個進程/線程在一個相同的IP地址和端口上偵聽,很簡單,這是由於TCP/IP模型將一個端口做爲一個四層複用解複用的惟一標 識,也就是一個四層地址,正如IP地址屬於一個主機同樣(屬於一塊網卡?),一個IP/端口對屬於一臺主機上一個特定的進程,它只是一個保證惟一性的靜態 標識。世界上不一樣的主機不能有相同的IP地址,一臺主機上綁定特定IP地址的不一樣進程也不能有相同的端口,不然就不知道一個流到底該交給哪一個進程!
想 象一下如今爲何reuseport可讓之前不可能的事變成可能。很簡單,在靜態因素以外加入了一個動態因素,那就是將發起鏈接的源IP和源端口也一塊兒 考慮了進來,四元組一塊兒作了一個簡單的hash計算,所得的結果對Listener數量取模,獲取哪一個Listener要爲這個鏈接服務。
事實 上,咱們發現,須要惟一標識的不是一個Listener,而應該是一個鏈接自己。TCP服務端在有客戶端企圖創建一個鏈接時纔有意義。那麼是什麼讓一個綁 定同一IP/端口的套接字只能Listen一次這麼一個限制存在了這麼久呢?我認爲答案有兩個方面,一方面是由於UNIX的進程模型,另外一方面是這個限制 在單核CPU時代工做的足夠好,又能夠避免不少問題。

       好吧,如今我將Listener和進程徹底分割開,我既不贊同綁定同一IP地址/端口的套接字只能Listen一次,又不贊同採用reuseport方 案,我暫且忽略了哪一個進程/線程在偵聽,假設根本沒有任何進程/線程偵聽的概念,我只求一個鏈接請求到來的時候,能夠成功完成三次握手,建立一個客戶 socket,而這個很簡單,新建立的客戶socket被放入一個池中,Listen的任務就完成了,在握手完成以前,與任何進程/線程都無關聯,接下來 把進程/線程考慮進來,它們來accept,也就是從一個池中獲取一個客戶socket來處理。事實上,我是分離了Listen和Accept,內核協議 棧只負責Listen,而進程/線程只負責Accept,問題就解決了。

雜亂不清的東西糾纏在一塊兒的時候,會引入不少複雜性,避免這些複雜性的方式就是把糾纏在一塊兒的東西剝離,海闊天空。同事爲我這個優化取了一個很好的名字,叫作Xsocket,這裏的X能夠理解成兩個意思,一個是「牛X」中的X,一個是「插」!!

今天感到特別累,可是卻又無比的高興,昨晚作了一個夢,感受今天會有驚喜,然而等了一天仍是未能如願,我再也不相信緣份了,但是最終我仍是改變了想法,緣份未盡,上帝讓個人驚喜來自於別處,雖然它並非我夢裏的那個。阿們...

socket

相關文章
相關標籤/搜索