PHP秒殺系統全方位設計分析(一)

OldBoy~發表於2018-01-08

秒殺系統特點
人多商品少
時間短流量高
外掛機器[黃牛和非黃牛]

技術分析
瞬間高併發的處理能力
多層次的分散式處理能力
人機互動與對抗[12306驗證碼圖片]

技術選型分析
Linux+Nginx+PHP+Mysql+Redis
CDN,智慧DNS,分散式快取,全國多節點,多線路接入
LVS負載均衡

基本功能和流程
後臺:活動管理/商品管理/訂單管理/日誌管理,資料列表和內容的編輯增刪(邏輯刪除)改查
前臺:商品展示/搶購/我的訂單/購物車/登入等功能
安全:驗證碼/回答/分析日誌,防攻擊、防作弊、防機器人

使用者大概訪問互動流程
使用者進來的時候先看到秒殺商品的展示頁面,然後從頁面選擇商品參與秒殺,參與秒殺時需要提交驗證碼,驗證使用者登入狀態等之類的驗證,把問答或者一些驗證資訊填完之後就可以提交訂單完成秒殺功能,然後等待結果,有可能成功或者失敗,提示一些資訊,使用者能夠感知到的秒殺流程。

使用者選擇想要秒殺的商品,輸入了要購買的商品數量,點選提交,這時候我們的秒殺程式就要開始響應了,於是秒殺開始。
先驗證使用者提交資訊,比如還有使用者登入狀態,驗證問答資訊或者更多的資訊。先驗證資訊是否對,如果有錯誤,那麼提示錯誤資訊,如果對,那麼進入庫存驗證,如果庫存不足,或者活動結束了,提示庫存不足,那麼秒殺結束。如果訂單提交成功,那麼生成訂單,生成訂單時會有訂單相關的資料處理,比如庫存的更新等。畢竟是併發提交,有可能生成訂單也會出現問題,如果生成訂單環節出現了問題,即使前面的環節通過,在此環節也會出現問題,比如訂單生成的時候,前面的一個人先生成了訂單,庫存不足了,還會出錯,所以在這個環節一定還會有其他的異常資訊出現,那麼還需要給使用者提交錯誤資訊,如果沒出錯,那麼秒殺成功。

以上大概流程是不可或缺的,也是有點粗略。如果我們流程僅僅這幾個點的話,那麼我們的流程中其實還差的很多。我們在設計過程中,先列出來,還需要根據這幾個流程進行補充。
程式執行起來會有幾個輸入的驗證:如問答的驗證,使用者登入狀態驗證,使用者是否進入黑名單,以及引數的驗證,商品資訊的引數,活動資訊的引數,其他校驗資訊的引數驗證等。
還有輸出的驗證:異常情況的輸出和成功正常情況的輸出。

其他情況:比如購買的庫存是一種商品的話,在處理的時候要容易一點,會做一下比較。如果是多件商品的話,每個商品就需要每個進行驗證。如果商品還有型別的區分,比如手機有好多種型號,那麼還需要根據型號處理。有的時候還會涉及到優惠券等等。。

資料庫設計
基本的資料模型大概有哪些?
活動資訊、商品資訊、訂單資訊、問答資訊等模型

---活動資訊表

CREATE TABLE `active` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '活動ID',
`title` varchar(255) NOT NULL COMMENT '活動名稱',
`time_begin` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '開始時間',
`time_end` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '結束時間',
`sys_dateline` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '建立時間',
`sys_lastmodify` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最後修改時間',
`sys_status` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '狀態,0 待上線,1 已上線,2 已下線',
`sys_ip` varchar(50) NOT NULL COMMENT '建立人IP',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='活動資訊表';

---商品資訊表

CREATE TABLE `goods` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`active_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '活動ID',
`title` varchar(255) NOT NULL COMMENT '商品名稱',
`description` text NOT NULL COMMENT '描述資訊,文字,要支援HTML',
`img` varchar(255) NOT NULL COMMENT '小圖示,列表中顯示',
`price_normal` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '原價',
`price_discount` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '秒殺價',
`num_total` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '總數量',
`num_user` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '單個使用者限購數量',
`num_left` int(11) NOT NULL DEFAULT '0' COMMENT '剩餘可購買數量',
`sys_dateline` int(11) NOT NULL DEFAULT '0' COMMENT '資訊建立時間',
`sys_lastmodify` int(11) NOT NULL DEFAULT '0' COMMENT '最後修改時間',
`sys_status` int(11) NOT NULL DEFAULT '0' COMMENT '狀態,0 待上線,1 已上線,2 已下線',
`sys_ip` varchar(50) NOT NULL COMMENT '建立人的IP',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='商品資訊表';

---日誌記錄表[用於做核查]

CREATE TABLE `ms_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '日誌ID',
`active_id` int(10) unsigned NOT NULL COMMENT '活動ID',
`uid` int(10) unsigned NOT NULL COMMENT '使用者ID',
`action` varchar(50) NOT NULL COMMENT '操作名稱',
`result` varchar(50) NOT NULL COMMENT '返回資訊',
`info` text NOT NULL COMMENT '操作詳情,JSON格式儲存,比如:POST,refer, 瀏覽器等資訊',
`sys_dateline` int(10) unsigned NOT NULL COMMENT '建立時間',
`sys_lastmodify` int(10) unsigned NOT NULL COMMENT '最後修改時間',
`sys_status` int(10) unsigned NOT NULL COMMENT '狀態,0 正常,1 異常,2 已處理的異常',
`sys_ip` varchar(50) NOT NULL COMMENT '使用者IP',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='秒殺的詳細操作日誌';

---問答資訊表[防止機器人黃牛]

CREATE TABLE `ms_question` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '問答ID',
`active_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '所屬活動ID',
`title` varchar(255) NOT NULL COMMENT '問題描述',
`ask1` varchar(255) NOT NULL COMMENT '問題1',
`answer1` varchar(255) NOT NULL COMMENT '答案1',
`ask2` varchar(255) NOT NULL,
`answer2` varchar(255) NOT NULL,
`ask3` varchar(255) NOT NULL,
`answer3` varchar(255) NOT NULL,
`ask4` varchar(255) NOT NULL,
`answer4` varchar(255) NOT NULL,
`ask5` varchar(255) NOT NULL,
`answer5` varchar(255) NOT NULL,
`ask6` varchar(255) NOT NULL,
`answer6` varchar(255) NOT NULL,
`ask7` varchar(255) NOT NULL,
`answer7` varchar(255) NOT NULL,
`ask8` varchar(255) NOT NULL,
`answer8` varchar(255) NOT NULL,
`ask9` varchar(255) NOT NULL,
`answer9` varchar(255) NOT NULL,
`ask10` varchar(255) NOT NULL,
`answer10` varchar(255) NOT NULL,
`sys_dateline` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '建立時間',
`sys_lastmodify` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最後修改時間',
`sys_status` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '狀態,0 正常,1 刪除',
`sys_ip` varchar(50) NOT NULL COMMENT '釋出人的IP',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='問答資訊表';

---訂單資訊表

CREATE TABLE `ms_trade` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '訂單ID',
`active_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '活動ID',
`goods_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '商品ID',
`num_total` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '購買的單品數量',
`num_goods` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '購買的商品種類數量',
`price_total` decimal(10,0) unsigned NOT NULL DEFAULT '0' COMMENT '訂單總金額',
`price_discount` decimal(10,0) unsigned NOT NULL DEFAULT '0' COMMENT '優惠後實際金額',
`time_confirm` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '確認訂單時間',
`time_pay` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '支付時間',
`time_over` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '過期時間',
`time_cancel` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '取消時間',
`goods_info` mediumtext NOT NULL COMMENT '訂單商品詳情,JSON格式儲存',
`sys_dateline` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '建立時間',
`sys_lastmodify` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最後修改時間',
`sys_status` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '狀態,0 初始狀態,1 待支付,2 已支付,3 已過期,4 管理員已確認,5 已取消,6 已刪除,7 已發貨,8 已收貨,9 已完成',
`sys_ip` varchar(50) NOT NULL COMMENT '使用者IP',
`uid` int(10) unsigned NOT NULL COMMENT '使用者ID',
`username` varchar(50) NOT NULL COMMENT '使用者名稱',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `active_id` (`active_id`),
KEY `goods_id` (`goods_id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8 COMMENT='訂單資訊表';

相關文章