熱愛技術、樂於分享的技術人,目前主要從事資料庫相關技術的研究。
前言對於計算機學科來說,計算機網路相關知識的重要性不言而喻。平時我們框架用的多了,對於底層網路 IO 的處理關注的並不算多(如果不讓你用 Spring,你還能寫出個 Web 介面嗎?),但對於中介軟體以及框架的開發者來說,網路 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 粘包問題的。如下圖所示:
https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_packets.html
MySQL協議
連線 DBLE 既然能像連線 MySQL 一樣,那 DBLE 一定要能夠處理 MySQL 的資料包,如何處理這些資料包在程式碼裡都有體現,我將在網路模組原始碼解析裡詳細講解 DBLE 對於 MySQL 資料包的處理。
三、BIO 與 NIODBLE 效能能夠如此之高,與它的高效能網路 IO 處理離不開關係。DBLE 中處理前端客戶端連線及後端 MySQL 資料庫連線都使用了 NIO 的方式,即 IO 多路複用技術。
在網路連線數較少的情況下透過 BIO+ 多執行緒的方式也能夠比較快速的處理請求,但隨著連線數的增多,執行緒間的切換帶來的效能損耗將大於多執行緒處理帶來的效能提升,從而導致整體效能下降。
而 NIO 即 IO 多路複用技術,能夠透過少量執行緒管理更多的連線。NIO 不會為每個連線建立一個處理執行緒,而只是在連線有資料的時候進行處理。NIO 再加上請求資料處理非同步化,是 DBLE 高效能的秘密。