問題終于找到,簡單的說是因?yàn)閖ava 序列化的效率低下,而ejb調(diào)用之間又大量使用序列化,因此造成極大的性能消耗,而且也影響到響應(yīng)時(shí)間。仔細(xì)分析了一下項(xiàng)目情況,呵呵,情況非常嚴(yán)重,系統(tǒng)架構(gòu)是按照三層來設(shè)計(jì)的,每個(gè)層都是ejb,調(diào)下一層都是通過遠(yuǎn)程接口,而且層之間可能還多個(gè)ejb的調(diào)用。
(說句題外話,這種設(shè)計(jì)個(gè)人感覺非常,恩,不理解,性能殺手,而且ejb配置極其復(fù)雜,當(dāng)然或者ejb本來就是如此,ebj和weblogic對我來說是很陌生很高深的東西,目前還沒有深入掌握。)
很自然的會(huì)想到ejb2.0中的配置項(xiàng)enable-call-by-reference,如果能夠開啟就可以避免遠(yuǎn)程接口調(diào)用中的序列化。檢查配置文件發(fā)現(xiàn)幾乎能設(shè)置enable-call-by-reference的地方都設(shè)置為true了,奇
怪,再檢查部署方式時(shí)發(fā)現(xiàn),恩,暈倒,被部署到不同的ear包中了。
不同的ear包,enable-call-by-reference就算設(shè)置位true也開啟不了吧?
接下來的改進(jìn)方式,很自然就想到,如果能打包到同一個(gè)ear中,就可以在不改動(dòng)代碼,不改動(dòng)部署文件的情況下解決這個(gè)問題,似乎是一個(gè)不錯(cuò)的好想法。
謹(jǐn)慎起見,同時(shí)為了拿到足夠的證據(jù)來說法上層,先做個(gè)試驗(yàn)先。
模擬公司的項(xiàng)目結(jié)構(gòu),單獨(dú)寫了一個(gè)project,1個(gè)servlet負(fù)責(zé)接受外界請求,3個(gè)SLSB模擬三層工作,ejb直接只提供遠(yuǎn)程接口,然后打包到同一個(gè)ear包進(jìn)行測試。當(dāng)然enable-call-by-reference設(shè)置為true
和false來進(jìn)行對比測試。
為了突出這個(gè)差異,ejb中都不進(jìn)行任何操作,也不sleep。這樣消耗就主要體現(xiàn)在java 序列化的消耗上,而且為了模擬真實(shí)情況,參數(shù)設(shè)置的比較大,里面放了1000個(gè)instance。
使用loadrunner,開啟100個(gè)測試線程,通過http訪問servlet,測試時(shí)間一分鐘,看能執(zhí)行多少次請求,測試結(jié)果如下:
enable-call-by-reference = false : 558
enable-call-by-reference = true : 21163
由于這個(gè)結(jié)果的差異性實(shí)在是太大了,因此沒有必要進(jìn)行多次測試,近40倍的差異完全可以反應(yīng)問題了,當(dāng)時(shí)實(shí)際項(xiàng)目中應(yīng)該遠(yuǎn)沒有這么夸張。
總結(jié)一下:
1. java serialize 非常慢
2. enable-call-by-reference可以有效避免這個(gè)開銷
因此,能enable-call-by-reference就盡量enable-call-by-reference。
ps:順便將這個(gè)測試的eclipse project也分享出來吧,請?jiān)谶@里下載
http://www.fs2you.com/files/045b367d-5d23-11dd-a2ed-0014221b798a/