高并發(fā)服務(wù)必須有一些緊急方案,比如服務(wù)熔斷,降級,隔離,限流,異步RPC等。服務(wù)熔斷,降級,隔離大家比較傾向于用netflix開源的分布式服務(wù)彈性框架Hystrix。Hystrix也可以限流。但是我們服務(wù)用的guava的RateLimiter這種成熟的令牌桶算法來實(shí)現(xiàn)。
服務(wù)限流是個(gè)很簡單的事情。我們的代碼也就幾百行,但是里面有一套比較完整的設(shè)計(jì)思想,目的是根據(jù)一定的策略(如:url, 平臺來源,url+平臺來源)來做一個(gè)業(yè)務(wù)細(xì)粒度的限流。
所有的請求都要走這個(gè)攔截器,這個(gè)攔截器里定義了一個(gè)單例的限流持有者,這個(gè)限流持有者按照配置的策略和配置的每個(gè)或者每種請求的限額來構(gòu)成的map來返回給攔截器請求對應(yīng)的key和RateLimiter。攔截器里判斷超限則直接返回錯(cuò)誤不交給控制器處理。一個(gè)請求類型,如url一個(gè)RateLimiter細(xì)粒度限流。
當(dāng)然,除了這種應(yīng)用級別的限流,在nginx層面也可以做一些對IP的session空間,請求頻率,并發(fā)量的限制。如果遇到網(wǎng)絡(luò)攻擊,盡量先從運(yùn)維層面去解決問題,因?yàn)樵酵蠈?,對服?wù)的影響能降到最低。
一個(gè)好的軟件架構(gòu)能夠滿足系統(tǒng)的品質(zhì),使受益人達(dá)成一致的目標(biāo),能夠支持計(jì)劃編制過程,對系統(tǒng)開發(fā)的指導(dǎo)性,能夠有效的管理復(fù)雜性,為復(fù)用奠定了基礎(chǔ),能夠降低維護(hù)費(fèi)用,能夠支持沖突分析。但是做到這些之前,先要從一些最基本的做起。比如我24歲就結(jié)婚了,不然怎么面向?qū)ο缶幊?。然后剛結(jié)婚就生娃了,不然對象跑了咋辦?new一個(gè)?創(chuàng)建銷毀開銷很大的,還是生個(gè)娃持續(xù)持有對象的引用的好。
絕大多數(shù)架構(gòu)或者編程語言的產(chǎn)生都是來源于項(xiàng)目。比如C++的發(fā)明者Stroustrup設(shè)計(jì)這個(gè)語言的初衷是看到C語言由于不合理的初始化參數(shù)導(dǎo)致至關(guān)重要的編程問題,這種bug很難發(fā)現(xiàn)。這種問題在清理的時(shí)候同樣出現(xiàn)。做了堅(jiān)持了,確實(shí)就成功了。然而任何一個(gè)東西都有一個(gè)形成和發(fā)展的階段。java在老一些的版本中一直被吐槽性能問題,而它的每一個(gè)版本都要伴隨著性能的提升,所以升級JVM就能帶來免費(fèi)的性能福利。細(xì)節(jié)處想到final關(guān)鍵字,在早期的版本中,final關(guān)鍵字的部分會內(nèi)聯(lián)調(diào)用,直接將函數(shù)展開,而不用不斷的參數(shù)入棧出棧而引起性能開銷。但是這個(gè)在函數(shù)體大的時(shí)候會有空間上比較大的開銷。JVM在1.5開始進(jìn)行了優(yōu)化,final關(guān)鍵字性能上的作用就不再那么大了。原來公司有個(gè)同事,人很好,也很有想法。他說:“我總是會將自己的一些想法記錄在一個(gè)本子上,然后過一段時(shí)間再看就會發(fā)現(xiàn),我那篇只堅(jiān)持了當(dāng)時(shí)的其中一個(gè)想法,去做了,都成功了。”我認(rèn)為