時間就像海綿里的水咐旧,只要愿擠掂骏,總還是有的嚣艇。
????????????????????????????????????????????????????????????——魯迅
問題分析二
1.項(xiàng)目改造點(diǎn)
加入log日志
2.多線程安全問題
(1)多線程安全演示案例
這里票的庫存有5萬承冰,5個線程,每一個線程調(diào)用一萬次sale方法食零,sale方法每次減掉一次庫存。
運(yùn)行效果:
庫存沒有被減到0寂屏,這里的主要原因是多線程操作共享變量多線程不安全贰谣。
(2)項(xiàng)目中多線程不安全的點(diǎn)
在通過RocketMQ消費(fèi)時進(jìn)行庫存扣減時會發(fā)生多線程不安全問題,原因很簡單迁霎,也是跟上個例子是一樣的吱抚。
這個地方是一個典型的多線程不安全的點(diǎn)。
(3)演示項(xiàng)目中多線程不安全
使用jmeter模擬高并發(fā)多線程考廉,使得RocketMQ也是多線程消費(fèi)秘豹,導(dǎo)致多線程不安全。
1昌粤、使用100個線程
2既绕、模擬下單接口
壓測前數(shù)據(jù):Mysq中查詢相關(guān)數(shù)據(jù):
訂單表為空啄刹,商品表13號goods_id的數(shù)量是573
分布式項(xiàng)目啟動
Jmeter壓測跑完
查看數(shù)據(jù)庫(shop_goods)產(chǎn)生了100條訂單
但是我們查看,商品表13號goods_id的數(shù)量是556
壓測前是:573凄贩,實(shí)際扣減下來誓军,沒有扣減100個。所以這里發(fā)生了多線程不安全疲扎。
查看日志信息佳簸,可以發(fā)現(xiàn)RocketMQ消費(fèi)者使用了多線程進(jìn)行了庫存扣減遣鼓。所以這里有多線程安全問題。
(4)解決項(xiàng)目中多線程安全問題
加鎖,解決多線程安全問題蛙粘。
再壓測一次。
壓測前庫存
壓測后庫存
所以但壮,這里我們需要在處理庫存這里加鎖么库,確保多線程安全。
當(dāng)然處理的方式不僅僅限制于synchronized
也可以使用ReentrantLock或者使用atomi的原子操作類(基于CAS機(jī)制)
同樣另外一個工程中久橙,情況會有些不同俄占,因?yàn)檫@個地方是使用優(yōu)惠券,每張優(yōu)惠券都是一條單條數(shù)據(jù)淆衷,一般又只有使用或者未使用的情況缸榄。
所以這里發(fā)生多線程不安全的幾率極小,當(dāng)然為了確保萬無一失祝拯,也可以加上鎖甚带。
3.冪等性問題
因?yàn)镽ocketMQ沒有辦法確保消息不重復(fù)。
1佳头、重試機(jī)制導(dǎo)致的問題鹰贵,消息成功發(fā)送到MQ中,但MQ因網(wǎng)絡(luò)原因未能成功返回康嘉,導(dǎo)致重試機(jī)制重試機(jī)制重復(fù)發(fā)送到MQ碉输。
2、消費(fèi)者成功消費(fèi)完消息亭珍,未返回consume_commit時敷钾,系統(tǒng)重啟|系統(tǒng)宕機(jī),MQ重新發(fā)送消息到同消息組其他消費(fèi)者機(jī)器肄梨,導(dǎo)致消息重復(fù)阻荒。
(1)項(xiàng)目中模擬消息重復(fù)
改造項(xiàng)目,在訂單系統(tǒng)中众羡,向RocketMQ發(fā)送兩次消息侨赡,模擬消息重復(fù)。
項(xiàng)目重啟。把訂單表清空羊壹。再次確認(rèn)下庫存信息1000
再次壓測100條數(shù)據(jù)
查看數(shù)據(jù)蓖宦。訂單表100條數(shù)據(jù)。
所以看到這里舶掖,發(fā)現(xiàn)這里有消息重復(fù)的問題球昨。需要冪等性處理。因?yàn)镽ocketMQ避免不了消息重復(fù)
(2)解決方案-去重表
利用數(shù)據(jù)庫表單的特性來實(shí)現(xiàn)冪等眨攘,常用的一個思路是在表上構(gòu)建唯一性索引主慰,保證某一類數(shù)據(jù)一旦執(zhí)行完畢,后續(xù)同樣的請求不再重復(fù)處理了鲫售。
當(dāng)用戶下單時共螺,會經(jīng)歷多個環(huán)節(jié),比如生成訂單情竹,減庫存藐不,減優(yōu)惠券等等。每一個環(huán)節(jié)執(zhí)行時都先檢測一下該訂單id是否已經(jīng)執(zhí)行過這一步驟秦效,對未執(zhí)行的請求雏蛮,執(zhí)行操作并緩存結(jié)果,而對已經(jīng)執(zhí)行過的id阱州,則直接返回之前的執(zhí)行結(jié)果挑秉,不做任何操作。這樣可以在最大程度上避免操作的重復(fù)執(zhí)行問題苔货,緩存起來的執(zhí)行結(jié)果也能用于事務(wù)的控制等犀概。
數(shù)據(jù)表:
shop_goods_unique
然后生成model,dao等等
(3)項(xiàng)目中使用去重表解決冪等性問題
每次在操作庫存時夜惭,往專屬的去重表中插入一條記錄姻灶,因?yàn)閛rder_id是唯一的,如果有兩次诈茧,那么第二次肯定插入不了产喉。
所以這里就直接返回,不再修改庫存敢会。
測試:(壓測前镊叁,恢復(fù)數(shù)據(jù),訂單表清空走触,庫存設(shè)置為1000)
壓測后
這里也可以在RocketMQ中確認(rèn)下應(yīng)該是對應(yīng)主題上有雙倍的數(shù)據(jù)。
但是沒有關(guān)系疤苹,有冪等性處理的話互广,消息重復(fù),業(yè)務(wù)上也是正常的。
當(dāng)然這里是遇到冪等性的消息是直接消費(fèi)惫皱。
如果是方案要完美的話像樊,有時候要進(jìn)行分析,可以消費(fèi)這類的消息旅敷,再把這類消息做為生產(chǎn)者寫入一個“重復(fù)消息”的主題生棍。方便對出現(xiàn)消息重復(fù)的地方進(jìn)行問題跟蹤和排查。
另外還有使用優(yōu)惠券這里也可以使用另外一張去重表媳谁。因?yàn)檫@樣就可以實(shí)現(xiàn)完全的分布式涂滴,訂單系統(tǒng)和會員系統(tǒng)數(shù)據(jù)庫也可以做一定分離。
4.壓力測試
(1)異步解耦
例如晴音,作為淘寶/天貓主站最核心的交易系統(tǒng)柔纵,每筆交易訂單數(shù)據(jù)的產(chǎn)生會引起幾百個下游業(yè)務(wù)系統(tǒng)的關(guān)注,包括物流锤躁、購物車搁料、積分、阿里媽媽系羞、流計算分析等等郭计,整體業(yè)務(wù)系統(tǒng)龐大而且復(fù)雜,架構(gòu)設(shè)計稍有不合理椒振,將直接影響主站業(yè)務(wù)的連續(xù)性昭伸。
通過加入RocketMQ,能夠解決高可用松耦合杠人,通過上勋乾、下游業(yè)務(wù)系統(tǒng)的松耦合設(shè)計,即便下游子系統(tǒng)(如物流嗡善、積分等)出現(xiàn)不可用甚至宕機(jī)辑莫,都不會影響到核心交易系統(tǒng)的正常運(yùn)轉(zhuǎn)。
通過RocketMQ的異步化設(shè)計罩引,可以靈活高效的適應(yīng)因業(yè)務(wù)快速發(fā)展而帶來的變化各吨,如新增業(yè)務(wù)系統(tǒng)。
項(xiàng)目中模擬下游系統(tǒng)卡頓
使用接口調(diào)用壓測數(shù)據(jù)
本機(jī)壓測:(5000個線程袁铐,5000個請求)
1揭蜒、使用HTTP調(diào)用
2、使用MQ異步解耦
明顯看到剔桨,使用了MQ屉更,壓測的數(shù)據(jù)。明顯好于接口調(diào)用洒缀,這個得意于MQ的異步解耦功能瑰谜。
如果我們模擬下游系統(tǒng)卡頓欺冀,那么這種差別會差別很大。
代碼上:在下游系統(tǒng)中加入2ms的休眠萨脑。
本機(jī)壓測:(5000個線程隐轩,5000個請求)
1、使用HTTP調(diào)用
2渤早、使用MQ異步解耦
經(jīng)過壓測可知职车,如果使用MQ的異步接口,其實(shí)在于上游系統(tǒng)(訂單系統(tǒng))來說鹊杖,基本上不會收到下游系統(tǒng)的波動的影響悴灵。
無論下游系統(tǒng)多卡,上游系統(tǒng)表現(xiàn)已經(jīng)很穩(wěn)定仅淑。
所以在淘寶称勋,每筆交易訂單數(shù)據(jù)的產(chǎn)生會引起幾百個下游業(yè)務(wù)系統(tǒng)的關(guān)注,包括物流涯竟、購物車赡鲜、積分、阿里媽媽庐船、流計算分析等等银酬,整體業(yè)務(wù)系統(tǒng)龐大而且復(fù)雜,如果使用接口調(diào)用筐钟,根本就不用玩了揩瞪,這就是為什么在阿里一定要用RocketMQ,不用就GG了篓冲。
5.RocketMQ的其他應(yīng)用場景
(1)削峰填谷
諸如秒殺李破、搶紅包、企業(yè)開門紅等大型活動時皆會帶來較高的流量脈沖壹将,或因沒做相應(yīng)的保護(hù)而導(dǎo)致系統(tǒng)超負(fù)荷甚至崩潰嗤攻,或因限制太過導(dǎo)致請求大量失敗而影響用戶體驗(yàn),削峰填谷是解決該問題的有效方式诽俯。
RocketMQ超高性能的消息處理能力可以承接流量脈沖而不被擊垮妇菱,在確保系統(tǒng)可用性同時,因快速有效的請求響應(yīng)而提升用戶的體驗(yàn)暴区。
確保下游業(yè)務(wù)在安全水位內(nèi)平滑穩(wěn)定的運(yùn)行闯团,避免超高流量的沖擊。
通過削峰填谷可控制下游業(yè)務(wù)系統(tǒng)的集群規(guī)模仙粱,從而降低投入成本房交。
(2)大數(shù)據(jù)分析
數(shù)據(jù)在"流動"中產(chǎn)生價值,傳統(tǒng)數(shù)據(jù)分析大多是基于批量計算模型伐割,而無法做到實(shí)時的數(shù)據(jù)分析涌萤,利用 RocketMQ 與流式計算引擎相結(jié)合淹遵,可以很方便的實(shí)現(xiàn)將業(yè)務(wù)數(shù)據(jù)進(jìn)行實(shí)時分析。
構(gòu)建應(yīng)用系統(tǒng)和分析系統(tǒng)的橋梁负溪,并將它們之間的關(guān)聯(lián)解耦,同時由于數(shù)據(jù)產(chǎn)生非臣醚祝快且數(shù)據(jù)量大川抡,需要非常高的可擴(kuò)展性。
可對接Storm/Spark實(shí)時流計算引擎须尚,亦可對接 Hadoop/ODPS 等離線數(shù)據(jù)倉庫系統(tǒng)崖堤。
像阿里、京東的雙十一耐床、618密幔,顯示下了多少訂單,金額破了多少個億撩轰,基本上都是基于流式計算的結(jié)果(數(shù)據(jù)還沒有完全入到DB中就已經(jīng)實(shí)時算出來的)胯甩。
(3)分布式緩存同步
天貓雙11大促,各個分會場琳瑯滿目的商品需要實(shí)時感知價格變化堪嫂,大量并發(fā)訪問數(shù)據(jù)庫導(dǎo)致會場頁面響應(yīng)時間長偎箫,集中式緩存因?yàn)閹捚款i限制商品變更的訪問流量,通過 RocketMQ 構(gòu)建分布式緩存皆串,實(shí)時通知商品數(shù)據(jù)的變化淹办。
通過消息實(shí)時推送的方式,讓數(shù)據(jù)實(shí)時得以更新恶复。
大量并發(fā)訪問商品數(shù)據(jù)庫怜森,減少頁面響應(yīng)時間。
大促眾多分會場谤牡,多緩存的架構(gòu)設(shè)計副硅,滿足對商品變更的大量訪問需求。
鏈接:?https://pan.baidu.com/s/1s_btCY2D-OiOyGdihvBleQ ?提取碼: gcmi?
我是嬈疆_蚩夢拓哟,讓堅持成為一種習(xí)慣想许,感謝各位大佬的:點(diǎn)贊、收藏和評論断序,我們下期見流纹!