网络聊天室项目介绍
文章目錄
- 項目介紹
- 項目地址
- 項目底層核心運行架構(gòu)
- 版本1
- 版本2
- BUG記錄
- 后續(xù)計劃
項目介紹
本項目主要是開發(fā)一個網(wǎng)絡(luò)傳輸中間組件,實現(xiàn)1對1和1對多的網(wǎng)絡(luò)通信,并且有效解決一些常用的丟包和粘包的問題。目前支持超大文件傳輸。
主要應(yīng)用場景:如網(wǎng)絡(luò)聊天室,當然可以擴展應(yīng)用
開發(fā)語言:Java
涉及技術(shù):NIO,高并發(fā).
項目地址
https://github.com/13days/socket-learn
當前版本在socket-learn/chatRoom_1_0/這個目錄下維護。
項目底層核心運行架構(gòu)
版本1
核心連接器,包括發(fā)送和接收兩部分,值得一提的是,發(fā)送和接收都是支持并發(fā)的。在發(fā)送字符串的時候我們把他封裝成一個包再拆分發(fā)送到網(wǎng)絡(luò)。
并發(fā)調(diào)度結(jié)構(gòu)入下:
在這個版本中,對于每一個客戶端/或服務(wù)端。他的接收和發(fā)送都必須連接到一個IoProvider的調(diào)度器上面。在調(diào)度器上面分別由讀線程和寫線程來分派任務(wù),其中讀線程監(jiān)聽,寫線程發(fā)送。所有的任務(wù)都會委派到線程池中取完成,最后完成時收到回調(diào)通知,重寫組織數(shù)據(jù)。并返回業(yè)務(wù)層做相應(yīng)的處理。
發(fā)送執(zhí)行調(diào)度流程如下:
其中SendDispatcher的兩條路徑分別是發(fā)送完一個Packet和繼續(xù)發(fā)送當前Packet的兩條路徑。
版本2
在這個版本中提供了更良好的代碼封裝。引入了3重緩沖機制,支持超大文件發(fā)送,并做了壓測,支持20WBPS,在此規(guī)模下,jvm消耗內(nèi)存僅由100M左右,并且支持更多的長連接數(shù),在壓測版本中,可能同時支持10w長連接,當然,連接量還和并發(fā)發(fā)送的頻率有關(guān),此消彼長。
運行數(shù)據(jù)流圖大致情況
在這里面你會看到上個版本沒有的東西,比如Frame幀的概念,比如Channel通道的概念。這是引入了3級緩沖所帶了的新實體。
為什么要引入3級緩沖呢?
當需要發(fā)送的數(shù)據(jù)量過大的時候,我們總不可能期望把數(shù)據(jù)都讀到內(nèi)存里然后再進行發(fā)送,這樣服務(wù)器內(nèi)存會飆升的!!!
所以我們引入了第一級緩沖,Channel通道的方式,和上個版本保存一致的是,上個版本的數(shù)據(jù)讀到Packet里,而這個版本Packet里面實際存放的是Channel。
當數(shù)據(jù)讀到Channel里面后,我們就和可以分批次去讀數(shù)據(jù)啦!當時還有兩個問題,讀多少數(shù)據(jù)進來呢?讀到的數(shù)據(jù)如何保證有序呢?這就引入了第2級緩沖。
在這里緩沖里我們定義了實體幀F(xiàn)rame(后面你會看到具體的數(shù)據(jù)結(jié)構(gòu)),每個幀由首部和實體構(gòu)成,根據(jù)首部我們可以構(gòu)建完整的數(shù)據(jù),這不僅解決了順序問題,還解決了消息粘包的問題!當然,我們不可能一次讀很少的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)中去,這樣會發(fā)送很多次本地的IO,大大降低了程序的執(zhí)行速率,但是,我們又不能一次把讀到的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)中去,這樣發(fā)送的數(shù)據(jù)過多,會大大減少并發(fā)量。
所以針對這個問題,我們采用了第3級緩沖,IoArgs,這是具體發(fā)送到網(wǎng)絡(luò)中的數(shù)據(jù),多個IoArgs組成一個Frame,IoArgs的大小可以根據(jù)實際環(huán)境進行配置。
這樣做的好處在哪呢?
這樣能做到持久層內(nèi)存>>運行內(nèi)存>單次網(wǎng)絡(luò)數(shù)據(jù)量
使得,并發(fā)量大大提升,網(wǎng)絡(luò)被充分利用,增加了服務(wù)器的穩(wěn)定性,多條數(shù)據(jù)真正并發(fā)發(fā)送
三級緩沖的數(shù)據(jù)結(jié)構(gòu)
Chanel = Frame+Frame+Frame…
Frame = (報文+實體) = IoArgs+IoArgs+IoArgs…
下面的內(nèi)容是介紹一下程序運行時的數(shù)據(jù)流圖
在上面的發(fā)送流圖中,我們可以看到大量使用了回調(diào)功能,比如回調(diào)發(fā)送下一個IoArgs,或者構(gòu)建下一個Frame或則回調(diào)到上層發(fā)送異常或者回調(diào)通知上層應(yīng)用完成處理等。
接送數(shù)據(jù)的執(zhí)行流圖‘
在TCP完成監(jiān)聽之后的回調(diào)任務(wù)如下
上面是一個線程在監(jiān)聽到有任務(wù)到達的回調(diào),通過幀的ID來構(gòu)建發(fā)送方發(fā)送過來的幀,在組裝成包的形式提供給應(yīng)用層使用。
BUG記錄
主要是空指針buff,如連接斷開促發(fā)。還有selectionkey沒有即使注銷掉的問題,導致其他鏈接無法使用。
后續(xù)計劃
后續(xù)打算擴展業(yè)務(wù)層相關(guān)的功能。
總結(jié)
- 上一篇: 解决Spring文件下载时文件损毁问题
- 下一篇: PUN☀️七、网络同步:Object S