1.怎么保證促銷商品不會(huì)超賣?
答:這個(gè)問題是我們當(dāng)時(shí)開發(fā)時(shí)遇到的一個(gè)難點(diǎn)金蜀,超賣的原因主要是下的訂單的數(shù)目和我們要促銷的商品的數(shù)目不一致導(dǎo)致的珠移,每次總是訂單的數(shù)比我們的促銷商品的數(shù)目要多,當(dāng)時(shí)我們的小組討論了好久塘砸,給出了好幾個(gè)方案來實(shí)現(xiàn):
第一種方案:在每次下訂單前我們判斷促銷商品的數(shù)量夠不夠节仿,不夠不允許下訂單,更改庫存量時(shí)加上一個(gè)條件掉蔬,只更改商品庫存大于0的商品的庫存廊宪,當(dāng)時(shí)我們使用ab進(jìn)行壓力測試,當(dāng)并發(fā)超過500眉踱,訪問量超過2000時(shí)挤忙,還是會(huì)出現(xiàn)超賣現(xiàn)象。所以被我們否定了谈喳。
第二種方案:使用mysql的事務(wù)加排他鎖來解決册烈,首先我們選擇數(shù)據(jù)庫的存儲(chǔ)引擎為innoDB,使用的是排他鎖實(shí)現(xiàn)的婿禽,剛開始的時(shí)候我們測試了下共享鎖赏僧,發(fā)現(xiàn)還是會(huì)出現(xiàn)超賣的現(xiàn)象。有個(gè)問題是扭倾,當(dāng)我們進(jìn)行高并發(fā)測試時(shí)淀零,對(duì)數(shù)據(jù)庫的性能影響很大,導(dǎo)致數(shù)據(jù)庫的壓力很大膛壹,最終也被我們否定了驾中。
第三種方案:使用文件鎖實(shí)現(xiàn)。當(dāng)用戶搶到一件促銷商品后先觸發(fā)文件鎖模聋,防止其他用戶進(jìn)入肩民,該用戶搶到促銷品后再解開文件鎖,放其他用戶進(jìn)行操作链方。這樣可以解決超賣的問題持痰,但是會(huì)導(dǎo)致文件得I/O開銷很大。
最后我們使用了redis的隊(duì)列來實(shí)現(xiàn)祟蚀。將要促銷的商品數(shù)量以隊(duì)列的方式存入redis中工窍,每當(dāng)用戶搶到一件促銷商品則從隊(duì)列中刪除一個(gè)數(shù)據(jù),確保商品不會(huì)超賣前酿。這個(gè)操作起來很方便患雏,而且效率極高,最終我們采取這種方式來實(shí)現(xiàn)
2.商城秒殺的實(shí)現(xiàn)?
答:搶購薪者、秒殺是如今很常見的一個(gè)應(yīng)用場景纵苛,主要需要解決的問題有兩個(gè):
1 高并發(fā)對(duì)數(shù)據(jù)庫產(chǎn)生的壓力
2 競爭狀態(tài)下如何解決庫存的正確減少("超賣"問題)
對(duì)于第一個(gè)問題,已經(jīng)很容易想到用緩存來處理搶購,避免直接操作數(shù)據(jù)庫攻人,例如使用Redis取试。第二個(gè)問題,我們可以使用redis隊(duì)列來完成怀吻,把要秒殺的商品放入到隊(duì)列中瞬浓,因?yàn)閜op操作是原子的,即使有很多用戶同時(shí)到達(dá)蓬坡,也是依次執(zhí)行猿棉,文件鎖和事務(wù)在高并發(fā)下性能下降很快,當(dāng)然還要考慮其他方面的東西屑咳,比如搶購頁面做成靜態(tài)的萨赁,通過ajax調(diào)用接口,其中也可能會(huì)出現(xiàn)一個(gè)用戶搶多次的情況兆龙,這時(shí)候需要再加上一個(gè)排隊(duì)隊(duì)列和搶購結(jié)果隊(duì)列及庫存隊(duì)列杖爽。高并發(fā)情況下,將用戶進(jìn)入排隊(duì)隊(duì)列紫皇,用一個(gè)線程循環(huán)處理從排隊(duì)隊(duì)列取出一個(gè)用戶慰安,判斷用戶是否已在搶購結(jié)果隊(duì)列,如果在聪铺,則已搶購化焕,否則未搶購,庫存減1铃剔,寫數(shù)據(jù)庫撒桨,將用戶入結(jié)果隊(duì)列。
3.購物車的原理?
答:購物車相當(dāng)于現(xiàn)實(shí)中超市的購物車键兜,不同的是一個(gè)是實(shí)體車元莫,一個(gè)是虛擬車而已。用戶可以在購物網(wǎng)站的不同頁面之間跳轉(zhuǎn)蝶押,以選購自己喜愛的商品,點(diǎn)擊購買時(shí)火欧,該商品就自動(dòng)保存到你的購物車中棋电,重復(fù)選購后,最后將選中的所有商品放在購物車中統(tǒng)一到付款臺(tái)結(jié)賬苇侵,這也是盡量讓客戶體驗(yàn)到現(xiàn)實(shí)生活中購物的感覺赶盔。服務(wù)器通過追蹤每個(gè)用戶的行動(dòng),以保證在結(jié)賬時(shí)每件商品都物有其主榆浓。
主要涉及以下幾點(diǎn):
1于未、把商品添加到購物車,即訂購
2、刪除購物車中已定購的商品
3烘浦、修改購物車中某一本圖書的訂購數(shù)量
4抖坪、清空購物車
5、顯示購物車中商品清單及數(shù)量闷叉、價(jià)格
實(shí)現(xiàn)購物車的關(guān)鍵在于服務(wù)器識(shí)別每一個(gè)用戶并維持與他們的聯(lián)系擦俐。但是HTTP協(xié)議是一種“無狀態(tài)(Stateless)”的協(xié)議,因而服務(wù)器不能記住是誰在購買商品握侧,當(dāng)把商品加入購物車時(shí)蚯瞧,服務(wù)器也不知道購物車?yán)镌扔行┦裁矗沟糜脩粼诓煌撁骈g跳轉(zhuǎn)時(shí)購物車無法“隨身攜帶”品擎,這都給購物車的實(shí)現(xiàn)造成了一定的困難埋合。
目前購物車的實(shí)現(xiàn)主要是通過cookie、session或結(jié)合數(shù)據(jù)庫的方式萄传。下面分析一下它們的機(jī)制及作用
cookie
cookie是由服務(wù)器產(chǎn)生甚颂,存儲(chǔ)在客戶端的一段信息。它定義了一種Web服務(wù)器在客戶端存儲(chǔ)和返回信息的機(jī)制盲再,cookie文件它包含域西设、路徑、生存期答朋、和由服務(wù)器設(shè)置的變量值等內(nèi)容贷揽。當(dāng)用戶以后訪問同一個(gè)Web服務(wù)器時(shí),瀏覽器會(huì)把cookie原樣發(fā)送給服務(wù)器梦碗。通過讓服務(wù)器讀取原先保存到客戶端的信息企垦,網(wǎng)站能夠?yàn)闉g覽者提供一系列的方便,例如在線交易過程中標(biāo)識(shí)用戶身份瑞躺、安全要求不高的場合避免用戶重復(fù)輸入名字和密碼醇份、門戶網(wǎng)站的主頁定制、有針對(duì)性地投放廣告等等斩例。利用cookie的特性雄人,大大擴(kuò)展了WEB應(yīng)用程序的功能,不僅可以建立服務(wù)器與客戶機(jī)的聯(lián)系念赶,因?yàn)閏ookie可以由服務(wù)器定制础钠,因此還可以將購物信息生成cookie值存放在客戶端,從而實(shí)現(xiàn)購物車的功能叉谜。用基于cookie的方式實(shí)現(xiàn)服務(wù)器與瀏覽器之間的會(huì)話或購物車旗吁,有以下特點(diǎn):
1、cookie存儲(chǔ)在客戶端停局,且占用很少的資源很钓,瀏覽器允許存放300個(gè)cookie香府,每個(gè)cookie的大小為4KB,足以滿足購物車的要求码倦,同時(shí)也減輕了服務(wù)器的負(fù)荷企孩;
2、cookie為瀏覽器所內(nèi)置叹洲,使用方便柠硕。即使用戶不小心關(guān)閉了瀏覽器窗口,只要在cookie定義的有效期內(nèi)运提,購物車中的信息也不會(huì)丟失蝗柔;
3、cookie不是可執(zhí)行文件民泵,所以不會(huì)以任何方式執(zhí)行癣丧,因此也不會(huì)帶來病毒或攻擊用戶的系統(tǒng);
4栈妆、基于cookie的購物車要求用戶瀏覽器必須支持并設(shè)置為啟用cookie胁编,否則購物車則失效;
5鳞尔、存在著關(guān)于cookie侵犯訪問者隱私權(quán)的爭論嬉橙,因此有些用戶會(huì)禁止本機(jī)的cookie功能。
1
2
3
4
5
session
session是實(shí)現(xiàn)購物車的另一種方法寥假。session提供了可以保存和跟蹤用戶的狀態(tài)信息的功能市框,使當(dāng)前用戶在session中定義的變量和對(duì)象能在頁面之間共享,但是不能為應(yīng)用中其他用戶所訪問糕韧,它與cookie最重大的區(qū)別是枫振,session將用戶在會(huì)話期間的私有信息存儲(chǔ)在服務(wù)器端,提高了安全性萤彩。在服務(wù)器生成session后粪滤,客戶端會(huì)生成一個(gè)sessionid識(shí)別號(hào)保存在客戶端,以保持和服務(wù)器的同步雀扶。這個(gè)sessionid是只讀的杖小,如果客戶端禁止cookie功能,session會(huì)通過在URL中附加參數(shù)愚墓,或隱含在表單中提交等其他方式在頁面間傳送窍侧。因此利用session實(shí)施對(duì)用戶的管理則更為安全、有效转绷。
同樣,利用session也能實(shí)現(xiàn)購物車硼啤,這種方式的特點(diǎn)是:
1议经、session用新的機(jī)制保持與客戶端的同步斧账,不依賴于客戶端設(shè)置;
2煞肾、與cookie相比咧织,session是存儲(chǔ)在服務(wù)器端的信息,因此顯得更為安全籍救,因此可將身份標(biāo)示习绢,購物等信息存儲(chǔ)在session中;
3蝙昙、session會(huì)占用服務(wù)器資源闪萄,加大服務(wù)器端的負(fù)載,尤其當(dāng)并發(fā)用戶很多時(shí)奇颠,會(huì)生成大量的session败去,影響服務(wù)器的性能;
4烈拒、因?yàn)閟ession存儲(chǔ)的信息更敏感圆裕,而且是以文件形式保存在服務(wù)器中,因此仍然存在著安全隱患荆几。
結(jié)合數(shù)據(jù)庫的方式
1
2
3
4
5
這也是目前較普遍的模式吓妆,在這種方式中,數(shù)據(jù)庫承擔(dān)著存儲(chǔ)購物信息的作用吨铸,session或cookie則用來跟蹤用戶行拢。這種方式具有以下特點(diǎn):
1、數(shù)據(jù)庫與cookie分別負(fù)責(zé)記錄數(shù)據(jù)和維持會(huì)話焊傅,能發(fā)揮各自的優(yōu)勢剂陡,使安全性和服務(wù)器性能都得到了提高;
2狐胎、每一個(gè)購物的行為鸭栖,都要直接建立與數(shù)據(jù)庫的連接,直至對(duì)表的操作完成后握巢,連接才釋放晕鹊。當(dāng)并發(fā)用戶很多時(shí),會(huì)影響數(shù)據(jù)庫的性能暴浦,因此溅话,這對(duì)數(shù)據(jù)庫的性能提出了更高的要求;
3歌焦、使cookie維持會(huì)話有賴客戶端的支持飞几。
1
2
3
各種方式的選擇:
雖然cookie可用來實(shí)現(xiàn)購物車,但必須獲得瀏覽器的支持独撇,再加上它是存儲(chǔ)在客戶端的信息屑墨,極易被獲取躁锁,所以這也限制了它存儲(chǔ)更多,更重要的信息卵史。所以一般cookie只用來維持與服務(wù)器的會(huì)話战转,例如國內(nèi)最大的當(dāng)當(dāng)網(wǎng)絡(luò)書店就是用cookie保持與客戶的聯(lián)系,但是這種方式最大的缺點(diǎn)是如果客戶端不支持cookie就會(huì)使購物車失效以躯。
Session能很好地與交易雙方保持會(huì)話槐秧,可以忽視客戶端的設(shè)置。在購物車技術(shù)中得到了廣泛的應(yīng)用忧设。但session的文件屬性使其仍然留有安全隱患刁标。
結(jié)合數(shù)據(jù)庫的方式雖然在一定程度上解決了上述的問題,但從上面的例子可以看出:在這種購物流程中涉及到對(duì)數(shù)據(jù)庫表的頻繁操作见转,尤其是用戶每選購一次商品命雀,都要與數(shù)據(jù)庫進(jìn)行連接,當(dāng)用戶很多的時(shí)候就加大了服務(wù)器與數(shù)據(jù)庫的負(fù)荷斩箫。
23.redis消息隊(duì)列先進(jìn)先出需要注意什么?
答:通常使用一個(gè)list來實(shí)現(xiàn)隊(duì)列操作吏砂,這樣有一個(gè)小限制,所以的任務(wù)統(tǒng)一都是先進(jìn)先出乘客,如果想優(yōu)先處理某個(gè)任務(wù)就不太好處理了狐血,這就需要讓隊(duì)列有優(yōu)先級(jí)的概念,我們就可以優(yōu)先處理高級(jí)別的任務(wù)易核,實(shí)現(xiàn)方式有以下幾種方式:
1)單一列表實(shí)現(xiàn):隊(duì)列正常的操作是 左進(jìn)右出(lpush,rpop)為了先處理高優(yōu)先級(jí)任務(wù)匈织,在遇到高級(jí)別任務(wù)時(shí),可以直接插隊(duì)牡直,直接放入隊(duì)列頭部(rpush)缀匕,這樣,從隊(duì)列頭部(右側(cè))獲取任務(wù)時(shí)碰逸,取到的就是高優(yōu)先級(jí)的任務(wù)(rpop)
2)使用兩個(gè)隊(duì)列乡小,一個(gè)普通隊(duì)列,一個(gè)高級(jí)隊(duì)列饵史,針對(duì)任務(wù)的級(jí)別放入不同的隊(duì)列满钟,獲取任務(wù)時(shí)也很簡單,redis的BRPOP命令可以按順序從多個(gè)隊(duì)列中取值胳喷,BRPOP會(huì)按照給出的 key 順序查看湃番,并在找到的第一個(gè)非空 list 的尾部彈出一個(gè)元素,redis> BRPOP list1 list2 0
list1 做為高優(yōu)先級(jí)任務(wù)隊(duì)列
list2 做為普通任務(wù)隊(duì)列
這樣就實(shí)現(xiàn)了先處理高優(yōu)先級(jí)任務(wù)吭露,當(dāng)沒有高優(yōu)先級(jí)任務(wù)時(shí)吠撮,就去獲取普通任務(wù)
方式1最簡單,但實(shí)際應(yīng)用比較局限讲竿,方式3可以實(shí)現(xiàn)復(fù)雜優(yōu)先級(jí)纬向,但實(shí)現(xiàn)比較復(fù)雜择浊,不利于維護(hù)
方式2是推薦用法,實(shí)際應(yīng)用最為合適