一直都隱隱約約的感覺TIM的網(wǎng)絡(luò)模型還是有點問題,但卻總說不出具體問題來。時不時就會想起這個事,今天在車上,終于恍然大悟。
也許是受wildfire和jabberd2的影響太深了(特別是wildfire),TIM中網(wǎng)絡(luò)和業(yè)務(wù)處理的聯(lián)系過于緊密,從套接口讀到數(shù)據(jù)流后,馬上就進入XML的PullParser分析階段,雖然之后有刻意的分離網(wǎng)絡(luò)操作和業(yè)務(wù)邏輯,但并不徹底。
有時候業(yè)務(wù)處理還是能夠感覺到網(wǎng)絡(luò)的存在,我覺得這是個不良的設(shè)計。
讓我耿耿于懷的,是Reactor的單線程特性。或許在某些情況下這是它的優(yōu)勢,但運用不當,就會成劣勢?,F(xiàn)在的TIM把業(yè)務(wù)邏輯和網(wǎng)絡(luò)IO都擠進了Reactor所控制的線程中,只要存在一點點的阻塞,吞吐率將大打折扣。
wildfire敢把網(wǎng)絡(luò)和業(yè)務(wù)綁得那么緊,是因為它采用的per-request,per-thread的模型,網(wǎng)絡(luò)IO引起的阻塞不會影響到其他request處理。我也沒有wildfire那么大的膽子采用per-request,per-thread,上下文切換的消耗不說,畢竟線程的數(shù)量也是有限制的,我很懷疑到底能承受多少連接數(shù),如果沒有記錯,Linux沒有重編譯內(nèi)核,一個進程內(nèi)最多是1024個線程,Windows能多些,好像是65535,數(shù)據(jù)可能不準確,但也說明了線程資源是有限的。同時,WFMOReactor在Windows下每個線程內(nèi)可同時監(jiān)視的句柄數(shù)(62個),也似乎太少了,這點也讓我煩惱。
仔細推敲后,我認為還是把網(wǎng)絡(luò)和業(yè)務(wù)完全脫離比較好一點,用至少一個線程專門操作套接口,突破WaitForMultipleObjects的句柄數(shù)限制,再用另外一個線程來完成業(yè)務(wù)。在業(yè)務(wù)線程上使用管道過濾器模式來一步一步的處理數(shù)據(jù)。當Reactor線程接收到數(shù)據(jù)后,放進MessageBlock里面,用Task框架來處理。
這種模型確實解決了原先的諸多毛病,但如果在這個時候改網(wǎng)絡(luò)模型,對整個項目是個不小的沖擊,極有可能導(dǎo)致在計劃的時間內(nèi)不能完成項目。猶豫了一下,為了保證品質(zhì),最終還是在SubVersion上創(chuàng)建了新的試驗分支。
