前言
對於計算機學科來說,計算機網絡相關知識的重要性不言而喻。平時我們框架用的多了,對於底層網絡 IO 的處理關注的並不算多(如果不讓你用 Spring,你還能寫出個 Web 接口嗎?),但對於中間件以及框架的開發者來說,網絡 IO 的處理卻是最需要關注的地方。
DBLE 的網絡模塊沒有用任何框架,完全是通過原生 JDK 純手寫的。研讀 DBLE 網絡模塊的源碼,能夠讓你對網絡 IO 的處理有更進一步的理解。為什麼連接 DBLE 能夠像連接 MySQL 一樣?為什麼 DBLE 的性能能夠如此高?希望通過本系列文章,能夠幫助大家對DBLE的網絡模塊有更深入的了解,更進一步,希望能夠幫助大家對高性能網絡 IO 有更深入的了解。
本篇作為 《DBLE 網絡模塊源碼解析》的第一篇,主要講講網絡 IO 的基礎知識。
一、TCP/IP 協議棧
TCP/IP 協議在一定程度上參考了 OSI 的體系結構。OSI 模型共有七層,從下到上分別是物理層、數據鏈路層、網絡層、運輸層、會話層、表示層和應用層。但是這顯然是有些複雜的,所以在 TCP/IP 協議中,它們被簡化為了四個層次,從下到上依次是鏈路層、網絡層、傳輸層和應用層。
不同層之間的數據封裝如下圖所示:
TCP/IP 協議棧不同層之間的數據封裝
從上圖可以看出上一層的協議數據都是作為下一層協議的消息體來傳輸的。所以協議從上到下,是一層一層封裝的結構。
二、MySQL 協議
MySQL 協議在 TCP/IP 協議棧中是處於應用層這一層。從而能夠知道 MySQL 協議數據是作為 TCP 協議中的消息體部分來傳輸的。
因為 TCP 為面向流的協議,沒有界限,會存在粘包拆包問題,需要在應用層解決。常見的解決方法有:
1. 消息定長,例如每個報文的大小為固定長度 100 字節,如果不夠,空位補空格;
2. 在包尾增加回車換行符進行分割,例如 FTP 協議;
3. 將消息分為消息頭和消息體,消息頭中包含表示消息總長度(或者消息體長度)的欄位;
4. 更複雜的應用層協議。
MySQL 協議是通過消息定長和在消息頭中包含消息體長度欄位的方法來解決 TCP 粘包問題的。如下圖所示:
MySQL協議
連接 DBLE 既然能像連接 MySQL 一樣,那 DBLE 一定要能夠處理 MySQL 的數據包,如何處理這些數據包在代碼裡都有體現,我將在網絡模塊源碼解析裡詳細講解 DBLE 對於 MySQL 數據包的處理。
三、BIO 與 NIO
DBLE 性能能夠如此之高,與它的高性能網絡 IO 處理離不開關係。DBLE 中處理前端客戶端連接及後端 MySQL 資料庫連接都使用了 NIO 的方式,即 IO 多路復用技術。
在網絡連接數較少的情況下通過 BIO+ 多線程的方式也能夠比較快速的處理請求,但隨著連接數的增多,線程間的切換帶來的性能損耗將大於多線程處理帶來的性能提升,從而導致整體性能下降。
而 NIO 即 IO 多路復用技術,能夠通過少量線程管理更多的連接。NIO 不會為每個連接創建一個處理線程,而只是在連接有數據的時候進行處理。NIO 再加上請求數據處理異步化,是 DBLE 高性能的秘密。
下期預告
本篇文章為 DBLE 網絡模塊源碼解析的第一篇,主要介紹了關於網絡 IO 的一些基礎知識。包括 TCP/IP 協議棧、應用層 MySQL 協議、BIO 和 NIO 相關知識,為後面的源碼解析做個鋪墊,下一篇將從源碼角度詳細講解 DBLE 的網絡處理邏輯,希望能夠對大家有所幫助。