 |
 |
去年的一個(gè)項(xiàng)目中,我設(shè)計(jì)了一個(gè)多線程的UDP通訊程式,由我方一臺(tái)主機(jī),分別對(duì)應(yīng)四地發(fā)送接收數(shù)據(jù)包。 在生產(chǎn)環(huán)境已經(jīng)非常穩(wěn)健的運(yùn)行了1年。 最近,隨著業(yè)務(wù)的增加,連接的遠(yuǎn)端增加到了12個(gè),也就是一個(gè)IP向12個(gè)IP發(fā)送接收數(shù)據(jù)包。 我在主線程中,管理這12個(gè)獨(dú)立的通訊線程,互不干擾,由于服務(wù)器是2U4核,所以該程式的設(shè)計(jì)具有一定可伸縮性。 但是,最近維護(hù)人員告訴,發(fā)現(xiàn)會(huì)發(fā)生某地業(yè)務(wù)停頓。一檢查,線程exception terminate。居然報(bào)的是:port already bind這個(gè)最常見的exception。但是在console里面,重啟這個(gè)線程,它又可以正常啟動(dòng),并穩(wěn)定的運(yùn)行。而且它每次發(fā)生的幾率很隨機(jī),有時(shí)候死掉1個(gè),有時(shí)死掉3個(gè),或者全部正常。 去年,該程式做過多次壓力測試,并沒發(fā)現(xiàn)這個(gè)問題,現(xiàn)在唯一導(dǎo)致它發(fā)生的原因就是線程增加了3倍。 仔細(xì)分析,發(fā)現(xiàn)多線程的啟動(dòng)方式,是在spring里面進(jìn)行管理和注冊(cè)jmx,每個(gè)線程都事先配置成mbean。啟動(dòng)的時(shí)候,注入一個(gè)map里,再循環(huán)啟動(dòng)。而udp通訊的方式是,隨機(jī)的由OS分配端口,會(huì)不會(huì)是線程的request太快,而OS沒有l(wèi)ock port cache的strategy,我想到這里于是在循環(huán)啟動(dòng)bean的方法里面,加了一個(gè)Thread.sleep(100)。再次測試,解決。 最后,我認(rèn)為os在分配隨機(jī)端口的時(shí)候,可能沒有鎖定機(jī)制,如果線程的request是高conconrent,就有可能出現(xiàn)重疊,而引發(fā)port lready bind 這個(gè)最簡單的錯(cuò)誤。要解決這個(gè)問題,第一就是盡量延長啟動(dòng)間隔,尤其是多路并發(fā)的server上,第二,人為的控制port的分配。
|
作者:未知 | 文章來源:未知 | 更新時(shí)間:2008-1-15 16:39:39
|
|
 |
 |
最新文章 |
|
|
 |