百度之后,找到這樣的思路:
需要一個(gè)排隊(duì)隊(duì)列和搶購(gòu)結(jié)果隊(duì)列及庫(kù)存隊(duì)列。高并發(fā)情況,先將用戶進(jìn)入排隊(duì)隊(duì)列,用一個(gè)線程循環(huán)處理從排隊(duì)隊(duì)列取出一個(gè)用戶,判斷用戶是否已在搶購(gòu)結(jié)果隊(duì)列,如果在,則已搶購(gòu),否則未搶購(gòu),庫(kù)存減1,寫(xiě)數(shù)據(jù)庫(kù),將用戶入結(jié)果隊(duì)列。
‘先將用戶進(jìn)入排隊(duì)隊(duì)列,用一個(gè)線程循環(huán)處理從排隊(duì)隊(duì)列取出一個(gè)用戶’
到底如何:"用一個(gè)線程循環(huán)處理",我就不明白該如何下手了,啥時(shí)候開(kāi)啟這個(gè)"線程"?
是不是每次用戶進(jìn)行抽獎(jiǎng),訪問(wèn)主程序就立即啟動(dòng)這個(gè)"線程"進(jìn)行循環(huán)處理隊(duì)列數(shù)據(jù)?
還是說(shuō),用戶點(diǎn)擊抽獎(jiǎng)按鈕,觸發(fā)的是執(zhí)行入隊(duì)操作,
然后,在服務(wù)器會(huì)有一個(gè)以cli方式啟動(dòng)的獨(dú)立進(jìn)程,在長(zhǎng)時(shí)間訂閱監(jiān)聽(tīng)隊(duì)列的情況,如果有數(shù)據(jù)就執(zhí)行用戶隊(duì)列的出列,然后再走下單操作?
入隊(duì)和出列,應(yīng)該是兩個(gè)不同的程序調(diào)用的吧?那如何在用戶一訪問(wèn)進(jìn)行抽獎(jiǎng),就能順利實(shí)現(xiàn)入隊(duì)和出列呢,如何在代碼層面安排好這些調(diào)用動(dòng)作的呢?
用一個(gè)線程循環(huán)處理",我就不明白該如何下手了,啥時(shí)候開(kāi)啟這個(gè)"線程"
"用一個(gè)線程循環(huán)處理",我就不明白該如何下手了,啥時(shí)候開(kāi)啟這個(gè)"線程"?
此程序使用blPop
或者brPop
堵塞獲取list的數(shù)據(jù)(這兩個(gè)方法的區(qū)別可看redis文檔得知),要堵塞的原因是,萬(wàn)一這一分鐘沒(méi)有數(shù)據(jù),過(guò)了30秒后數(shù)據(jù)進(jìn)來(lái)了,就要再等30秒才能處理。堵塞的最大時(shí)間我設(shè)了59秒。同時(shí)為了兼容大量數(shù)據(jù)的情況,此程序會(huì)循環(huán)從list讀數(shù)據(jù),每次讀數(shù)據(jù)用的都是堵塞方式,所以每次堵塞的時(shí)間都會(huì)根據(jù)當(dāng)前程序運(yùn)行的時(shí)長(zhǎng)動(dòng)態(tài)改變。理論上如果業(yè)務(wù)不復(fù)雜,這個(gè)程序運(yùn)行一次不會(huì)超過(guò)60秒,也就達(dá)到要求了,如果超過(guò)了60秒,也會(huì)自動(dòng)新增線程來(lái)執(zhí)行下一次循環(huán)。
你接下來(lái)的問(wèn)題有點(diǎn)不理解,你是了解大的流程的,我說(shuō)一下這個(gè)流程里的細(xì)節(jié)吧
我是用redis的list的,其它答案里有提到用鎖,如果是你這個(gè)方案,完全不需要用鎖,因?yàn)閘ist已經(jīng)為你解決了并發(fā)問(wèn)題。
只要用戶點(diǎn)了“搶”,你就把用戶的信息lPush
或者rPush
進(jìn)一個(gè)list,這時(shí)會(huì)返回一個(gè)int,就是告訴你這個(gè)操作之后,list里有多少條數(shù)據(jù)了,這個(gè)int是線程安全的,即使再高的并發(fā),也不會(huì)造成這個(gè)int對(duì)于這個(gè)用戶來(lái)說(shuō)已經(jīng)過(guò)時(shí),所以你可以判斷這個(gè)int有沒(méi)有超過(guò)庫(kù)存,如果超過(guò)了,直接告訴前端這個(gè)用戶錯(cuò)過(guò)秒殺了,如果否,則讓前端等待搶購(gòu)結(jié)果。(此時(shí)并不需要把超過(guò)庫(kù)存的用戶從list里刪除。庫(kù)存數(shù)建議在秒殺前查詢出來(lái)放到redis中,之后也不要修改redis的庫(kù)存數(shù),因?yàn)檫@個(gè)庫(kù)存數(shù)是專(zhuān)門(mén)用于跟list長(zhǎng)度做對(duì)比的)
接下來(lái)的步驟就根據(jù)不同的業(yè)務(wù)需求了,如果接下來(lái)要用戶填寫(xiě)補(bǔ)充信息,則最簡(jiǎn)單了:寫(xiě)一個(gè)接口接收用戶補(bǔ)充的信息,查詢list中用戶排第幾,跟庫(kù)存對(duì)比一下他是不是真的秒殺到了,然后做入庫(kù)操作。
如果接下來(lái)沒(méi)有讓用戶操作的需要了,則跟上面回答你第一個(gè)疑問(wèn)那樣,寫(xiě)一個(gè)堵塞輪詢的接口。
$ttl = 4;
$random = mt_rand(1,1000).'-'.gettimeofday(true).'-'.mt_rand(1,1000);
$lock = fasle;
while (!$lock) {
$lock = $redis->set('lock', $random, array('nx', 'ex' => $ttl));
}
if ($redis->get('goods.num') <= 0) {
echo ("秒殺已經(jīng)結(jié)束");
//刪除鎖
if ($redis->get('lock') == $random) {
$redis->del('lock');
}
return false;
}
$redis->decr('goods.num');
echo ("秒殺成功");
//刪除鎖
if ($redis->get('lock') == $random) {
$redis->del('lock');
}
return true;
來(lái)源 http://coffeephp.com/articles...
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專(zhuān)業(yè)的國(guó)家
北大青鳥(niǎo)中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過(guò)二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。