就servlet規(guī)范本身,數(shù)據(jù)可以放在3個地方:request、session、servletContext.
request:
好處:用完就仍,不會導(dǎo)致資源占用的無限增長。
弊處:每次要用都從數(shù)據(jù)庫中抓,多做操作,自然會對性能有一些影響。
session:
好處:不用每次都去數(shù)據(jù)庫抓,少做操作。
弊處:每個客戶都有一個session,只能自己使用,不同session可能保存大量重復(fù)數(shù)據(jù);
可能耗費大量服務(wù)器內(nèi)存;
另外session構(gòu)建在cookie和url重寫的基礎(chǔ)上,所以用session實現(xiàn)會話跟蹤,會用掉一點點服務(wù)器帶寬和客戶端保持聯(lián)絡(luò),
當(dāng)然session越多,耗費的帶寬越多,理論上也會對性能造成影響。
集群的session同步會是個問題。
servletContext:
好處:不用每次都去數(shù)據(jù)庫抓,少做操作。
存儲的數(shù)據(jù)所有客戶都可以用。
可減少重復(fù)在內(nèi)存中存儲數(shù)據(jù)造成的開銷。
弊處:很多時候相同的數(shù)據(jù)可能不多(相當(dāng)于cache的命中率很低)。
其實以上3中方法都有利有弊,各自的好處在某種條件下,也都會轉(zhuǎn)變?yōu)楸滋帯K圆环辆C合使用,相當(dāng)于一個“第三方用法”(只講一下思路,否則太過繁瑣,涉及到的相關(guān)技術(shù)點請參考有關(guān)技術(shù)資料):
request不說了,重點說說session和servletContext:
--session的可控應(yīng)用
session的最大問題是資源回收,兩類回收方法:
主動回收:瀏覽器被關(guān)閉,而為提交觸發(fā)清理動作的請求時,該方法失效,而且很常見。
超時回收:設(shè)置session的setMaxInactiveInterval屬性或在web.xml中配置超時時間,然后交給jvm的垃圾處理器處理。
不過不要報太大希望,jvm的垃圾收集器并不靈光。
可以用另一種替代方法緩解該問題,比如限制session的數(shù)量,可以用HttpSessionListener實現(xiàn),這樣可以緩解session帶來的吃內(nèi)存問題,當(dāng)然這種做法每次都需要判斷session數(shù)量,當(dāng)session達(dá)到限定數(shù)量時還必須用其他方法處理了,這些細(xì)節(jié)繁瑣,而且要謹(jǐn)慎處理。
--servletContext
如果說session是一個“局部緩存”,那servletContext就是一個“全局緩存”了,不妨把它當(dāng)作cache(這里不講究用詞的嚴(yán)謹(jǐn)性,僅為了更好說明問題)。cache的大小是當(dāng)前應(yīng)用可使用的最大內(nèi)存。cache的最大問題是提高命中率,命中率高,內(nèi)存占用少,效率高,命中率低,則內(nèi)存占用多而且效率低。這種應(yīng)用的技術(shù)實現(xiàn)比“session的可空應(yīng)用”要簡單,適用于相同數(shù)據(jù)多的地方,這個要事先有所判斷,如果用不好則有弊無利。
如果僅使用servlet規(guī)范給出的3種機制,任何一種都達(dá)不到好處兼收的效果,所以要發(fā)揮3種方法的好處、摒棄弊處,必須綜合運用,做一些技術(shù)框架的構(gòu)建工作,而且有些地方還比較繁瑣(還好框架是可重用的)。
有時候?qū)で蠡驅(qū)崿F(xiàn)“平衡”(或者說盡取其利而摒其害),要付出很大代價,根據(jù)不同的情況,這些代價或是值得,或是不值得。也可以“兩害相權(quán)取其輕”,或許是最便捷的方法。