tomcat - java數(shù)據(jù)存放問題
問題描述
如題,有登陸的系統(tǒng),老項(xiàng)目沒cache(我沒權(quán)利去加),但是不同的服務(wù)都要使用先前http請(qǐng)求到的數(shù)據(jù)(由用戶區(qū)分),想把它保存起來避免每次重復(fù)發(fā)http請(qǐng)求浪費(fèi)資源。
后臺(tái)springmvc
目前我想到3個(gè)方法:
1.丟session里面(HttpSessionListener),應(yīng)該最簡單,但不知道潛在問題2.丟threadlocal里面(controller搞個(gè)static 的threadlocal的變量,或者寫個(gè)contextholder)3.controller搞個(gè)ConcurrentHashMap的成員,把數(shù)據(jù)按<用戶id,http請(qǐng)求拿到的數(shù)據(jù)>放進(jìn)去.但是這個(gè)肯定不可行,可能會(huì)導(dǎo)致堆區(qū)OOF
說說第2個(gè)方案可能存在的問題。1.網(wǎng)上說的可能內(nèi)存泄露問題,導(dǎo)致PermGen出現(xiàn)OOF,原文連接ThreadLocal 內(nèi)存泄露的實(shí)例分析
我不確定是否會(huì)出現(xiàn)問題(原文有點(diǎn)看不懂),因?yàn)門hreadLocalMap的set具有保護(hù)機(jī)制
2.會(huì)不會(huì)出現(xiàn)請(qǐng)求線程里面的數(shù)據(jù)串了,比如1個(gè)請(qǐng)求線程同時(shí)服務(wù)兩個(gè)用戶(A和B)請(qǐng)求,B把自己的數(shù)據(jù)放到請(qǐng)求線程,覆蓋了A的,而請(qǐng)求線程服務(wù)A的時(shí)候,拿到了B的數(shù)據(jù)。。
問題解答
回答1:方法1是最簡單、最常用的,如果用戶量太大,或者做了負(fù)載均衡,就要實(shí)現(xiàn)集中存儲(chǔ)的Session,有很多現(xiàn)成的方案可以支持集中存儲(chǔ)的HttpSession的,存Redis、MongoDB、MySQL的都有,GitHub上搜一下。
方法2不解決問題,主要是因?yàn)橛脩舻卿浐螅啻握?qǐng)求可能會(huì)落在多個(gè)線程里。你說的第二點(diǎn)也是理由。
方法3也是一種實(shí)現(xiàn)方式,其實(shí)Tomcat的HttpSession就是用ConcurrentHashMap實(shí)現(xiàn)的(只是它用sessionId而不是用userId做key),但要注意的一點(diǎn)是,你必須自己管理Map中每個(gè)Key-Value的生命周期,例如Session超時(shí)了要及時(shí)remove掉。
相關(guān)文章:
1. 老師 我是一個(gè)沒有學(xué)過php語言的準(zhǔn)畢業(yè)生 我希望您能幫我一下2. mysql如何配置遠(yuǎn)程php外網(wǎng)鏈接數(shù)據(jù)庫3. mysql - eclispe無法打開數(shù)據(jù)庫連接4. mysql 5萬張表 導(dǎo)出成sql 不要內(nèi)容,只要結(jié)構(gòu),非常慢。如何解決啊?5. 數(shù)據(jù)庫 - mysql中有沒查看數(shù)據(jù)大小的函數(shù)??6. 導(dǎo)入數(shù)據(jù)庫不成功7. PHP單例模式8. mysql - 關(guān)于數(shù)據(jù)緩存策略方面的疑惑9. mysql如何判斷數(shù)據(jù)不存在則插入呢?10. mysql無法刪除字段(錯(cuò)誤1091),但是對(duì)該字段設(shè)置主鍵后就可刪除,為什么?
