? ? ? ? NETTY作為優(yōu)秀的NIO通訊框架择懂,深受大家喜愛罪郊,在我們的發(fā)版工具項目啟動時赏寇,便采用其作為通訊框架嫁赏,但是使用過程中卻踩了一個坑。
踩坑分析報告
項目簡介:
在發(fā)版工具項目中脖隶,由于發(fā)版過程會涉及不同的發(fā)版環(huán)境扁耐,對于一次請求,對應(yīng)的服務(wù)提供方IP需根據(jù)此次請求消息的附加信息確定产阱,同時考慮到多次請求建鏈的消耗過程婉称,選擇通訊方式為長連接;而考慮到連接的管理和并發(fā)控制問題构蹬,所以加入連接池王暗。對于NETTY通訊框架,本身已提供連接池庄敛,可通過數(shù)行代碼完成連接池定制過程俗壹,故選擇NETTY的SimpleChannelPool連接池,同時使用AbstractChannelPoolMap<InetSocketAddress,SimpleChannelPool>管理對應(yīng)不同IP地址的連接池藻烤。
異常場景:
連接池的使用過程為:根據(jù)請求數(shù)據(jù)傳入的IP信息绷雏,從AbstractChannelPoolMap中選定對應(yīng)的連接池,進(jìn)行后續(xù)通訊過程怖亭。有一次涎显,系統(tǒng)啟動后,異常場景出現(xiàn)了兴猩,傳入的IP為“36.0.12.112”棺禾,但是從MAP中通過連接池獲取連接時,顯示連接IP為“36.0.12.114”G吞1焐簟!
異常場景分析:
首先蛀醉,從連接池初始化過程看起悬襟,初始化代碼如下:
該初始化過程發(fā)生在此地址對應(yīng)的第一筆交易時,
如此詭異的問題脊岳,“并發(fā)問題”首先作為了我們的首要嫌疑犯。
? ? ? ? 首先進(jìn)行場景的補全和確認(rèn)過程垛玻,測試環(huán)境的日志還在割捅,為我們保留了完整的“犯罪”現(xiàn)場。從代碼看帚桩,業(yè)務(wù)代碼中存在同步調(diào)用和異步調(diào)用兩個方法亿驾,但代碼都基本類似,使用過程一般調(diào)用同步方法账嚎,即使用圖一的連接池創(chuàng)建過程莫瞬。從日志來看儡蔓,在進(jìn)程啟動后,第一批交易發(fā)起過程即出現(xiàn)了該問題疼邀,一筆請求對應(yīng)發(fā)送到五個不同的IP地址喂江,則問題應(yīng)該發(fā)生在連接池創(chuàng)建過程或者獲取過程中,但是如圖一所示旁振,已經(jīng)使用同步代碼塊進(jìn)行控制获询,雖然此同步代碼塊作用不詳(此處有伏筆),創(chuàng)建過程由不同線程創(chuàng)建不同的連接池拐袜,應(yīng)該不會出現(xiàn)問題筐付,難道MAP存在并發(fā)問題?然后就開始越走越遠(yuǎn)阻肿,甚至懷疑人生瓦戚。。丛塌。较解。
? ? ? ? 此時,有位同事大神說赴邻,已在本地復(fù)現(xiàn)印衔,瞬間感覺要看到了光明,但瞬間又熄滅了姥敛。能復(fù)現(xiàn)問題的測試代碼是在圖一的基礎(chǔ)上去掉了同步代碼塊奸焙,那看來同步代碼塊還是有作用的,但這并不是問題場景呀彤敛。放佛又陷入了無法解決之坑与帆,這會兒,見證了詭異現(xiàn)象的老師忽然靈光一閃墨榄,出現(xiàn)異常場景的時候玄糟,跟平時流程有所出入,調(diào)用的方法不是同步方法袄秩,而是異步方法阵翎,而異步方法中正好沒加入同步代碼塊控制。
? ? ? ? 終于事件大白啦之剧,可見混亂中的場景復(fù)現(xiàn)是多么的重要郭卫。到此,基本可以看到坑的面貌啦背稼,接下來就是詳細(xì)的分析過程了贰军。
? ? ? ? 如圖四所示,連接池在初始化過程中需要傳入第一個參數(shù)為bootstrap雇庙,由于對應(yīng)IP不同谓形,所以需要調(diào)用bootstrap.remoteAddress(paramK)進(jìn)行賦值,重點來了疆前,bootsrap實例是作為該類的成員變量存在的寒跳,但是bootstrap本身并不是線程安全的。
? ? ? ? 在并發(fā)情況下竹椒,該賦值過程會出現(xiàn)問題童太,導(dǎo)致MAP中KEY值的IP地址與VALUE中連接池真正的地址信息不符,所以會出現(xiàn)根據(jù)地址A拿到的連接卻指向地址B的詭異現(xiàn)象胸完。
異常場景分析總結(jié):
一次踩坑的排查終于結(jié)束啦书释,曲曲折折,不過為以后問題排查點出了很多注意的事項赊窥。
一:一定一定一定要最大限度了解異常場景爆惧,不要想當(dāng)然;
二:對測試環(huán)境出現(xiàn)問題保持敏感锨能,并發(fā)問題一般比較詭異扯再,很多問題在你放過后可能后續(xù)表現(xiàn)都正常,但是它仍然還在隱患中址遇,可能上線后就暴露出來了熄阻,所以不要放過測試環(huán)境的詭異問題。