聊聊小背景
前幾天的早晨我早寫字樓門口干等了半小時(shí),背后的原因竟然是健康碼的二維碼刷不出來(lái),保安小哥還一直跟我講,支付寶出不來(lái)你用微信啊,用微信啊。。
他們用的相同的接口,我用微信有卵用啊,冷風(fēng)中我甩了甩僅有的幾根秀發(fā),揚(yáng)長(zhǎng)而去。。。
作為程序員的我就開始了內(nèi)心的吐槽大會(huì):這咋做的啊,不行呀,這就打不開了,肯定沒(méi)做優(yōu)化,肯定沒(méi)用緩存,肯定沒(méi)做壓力測(cè)試。。。。。
下面作為技術(shù)的視角來(lái)分析下這個(gè)場(chǎng)景的實(shí)現(xiàn),以及可以怎么去優(yōu)化。這只是我YY哈,真實(shí)場(chǎng)景別人是怎么實(shí)現(xiàn)的我也不清楚哈。
需求剖析
每個(gè)人都有一個(gè)對(duì)應(yīng)的健康碼,健康碼分為幾種顏色,也就對(duì)應(yīng)了幾個(gè)狀態(tài)。本質(zhì)上就是通過(guò)健康碼的顏色能否區(qū)分這個(gè)用戶是否去過(guò)高風(fēng)險(xiǎn)地址。
首先第一個(gè)問(wèn)題就是需要根據(jù)多維度的數(shù)據(jù)去計(jì)算出這個(gè)碼的顏色,比如根據(jù)用戶的行動(dòng)軌跡去分析。至于實(shí)際上有哪些維度我也不知道,大概猜測(cè)行動(dòng)軌跡肯定是其中一點(diǎn)。
大概的存儲(chǔ)也很簡(jiǎn)單,就是userId code等字段,這個(gè)場(chǎng)景如果需要?dú)v史數(shù)據(jù)可以單獨(dú)歸檔即可,只留最近一天的數(shù)據(jù)提供查詢即可。
實(shí)現(xiàn)剖析
最簡(jiǎn)單的方案就是每次查詢實(shí)時(shí)去分析,這樣結(jié)果的真實(shí)性更高,不足點(diǎn)在于體驗(yàn)不是很好,如果邏輯多的話肯定是無(wú)法在1s內(nèi)給用戶響應(yīng)的,所以在上面分析的時(shí)候我們?cè)O(shè)計(jì)了一張表進(jìn)行存儲(chǔ),肯定是提前計(jì)算好的,比如一天一次,半天一次之類的形式。
那我們基于已經(jīng)有表的形式去做分析,這個(gè)業(yè)務(wù)場(chǎng)景就是很典型的讀多寫(凌晨寫)少的場(chǎng)景。如果不做任何改動(dòng),每次請(qǐng)求直接查詢表直接響應(yīng)即可。在高并發(fā)場(chǎng)景下只能依賴數(shù)據(jù)庫(kù)的并發(fā)能力來(lái)扛住這些請(qǐng)求,很容易出現(xiàn)系統(tǒng)掛掉,響應(yīng)慢的情況,也就是為什么我在門口等了半小時(shí)的原因。
增加緩存
最好的方式就是加緩存了,直接將碼的內(nèi)容緩存起來(lái),前端根據(jù)內(nèi)容生成健康碼即可。首先這種場(chǎng)景不能再查詢之后加緩存,因?yàn)榇蟛糠秩说谋O(jiān)控碼可能也就早晨進(jìn)公司的時(shí)候用一次,所以不適合查詢后再寫緩存的操作。
需要在凌晨計(jì)算每個(gè)人健康碼的時(shí)候,同時(shí)將數(shù)據(jù)寫一份到緩存中,當(dāng)然這個(gè)可以根據(jù)平時(shí)的訪問(wèn)的數(shù)據(jù)進(jìn)行分析,哪部分人每天都會(huì)用到,只預(yù)先緩存這一部分人的即可。
緩存后,基本上90%的請(qǐng)求都能命中緩存了,因?yàn)槊刻焐习嗟倪@部分人基本上不會(huì)有太大的變化。剩下的請(qǐng)求用數(shù)據(jù)庫(kù)去扛,如果還是扛不住可以加大緩存存儲(chǔ)量,用空間換時(shí)間。或者數(shù)據(jù)庫(kù)多搞幾個(gè)從節(jié)點(diǎn)即可。
內(nèi)外部隔離
在架構(gòu)設(shè)計(jì)中,隔離也是非常重要的一環(huán)。隔離的作用就是為了在出問(wèn)題的時(shí)候?qū)⒐收戏秶档偷阶钚 ?/p>
這健康碼的這個(gè)場(chǎng)景中,首先健康碼自己有一個(gè)專屬的APP,在支付寶刷不出來(lái)的時(shí)候我特意用它自己的APP去試了一下,同樣也是打不開。
也就是說(shuō)查詢健康碼是一個(gè)獨(dú)立的服務(wù),這個(gè)服務(wù)可能會(huì)被內(nèi)部的產(chǎn)品,比如APP調(diào)用,也有可能會(huì)通過(guò)Open API暴露給外部渠道調(diào)用,比如支付寶。
這個(gè)健康碼需要做什么隔離?
數(shù)據(jù)庫(kù)隔離
可以獨(dú)立出一個(gè)或多個(gè)從節(jié)點(diǎn)給對(duì)應(yīng)的服務(wù)進(jìn)行隔離,比如內(nèi)部服務(wù)用庫(kù)1,外部服務(wù)用庫(kù)2,相互不影響。
服務(wù)隔離
庫(kù)隔離了不能解決根據(jù)問(wèn)題,服務(wù)還得隔離。區(qū)分內(nèi)部服務(wù),外部服務(wù)。Open API只連接外部服務(wù),內(nèi)部的網(wǎng)關(guān)只連接內(nèi)部服務(wù)。
調(diào)用方限流
針對(duì)不同的調(diào)用方做不同的限制,內(nèi)部服務(wù)允許80%的量都可以滿足。外部服務(wù)20%的量可以滿足。這樣在壓力大的情況下,自己內(nèi)部的產(chǎn)品是影響最小的。也就是你在支付寶可能打不開健康碼,在我自己的APP可以打開。
不過(guò)這種還是得根據(jù)實(shí)際場(chǎng)景去分析,像健康碼這種場(chǎng)景,也許外部的訪問(wèn)量遠(yuǎn)遠(yuǎn)超過(guò)了內(nèi)部的量,因?yàn)榇蟛糠秩丝赡芏际怯弥Ц秾殻⑿虐∪ゴ蜷_。所以可以根據(jù)實(shí)際場(chǎng)景去限制流量。