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