自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

12306系統(tǒng)深度優(yōu)化之預(yù)扣庫(kù)存,異步下單,MySQL高可用

數(shù)據(jù)庫(kù) MySQL
在節(jié)假日和春節(jié)時(shí)候,火車(chē)票提前預(yù)售。在預(yù)售的點(diǎn)會(huì)有大量人們搶購(gòu)車(chē)票。由于高并發(fā),導(dǎo)致服務(wù)癱瘓。本篇就帶給大家12306系統(tǒng)深度優(yōu)化。

[[406897]]

一、12306深度優(yōu)化整體架構(gòu)

在節(jié)假日和春節(jié)時(shí)候,火車(chē)票提前預(yù)售。在預(yù)售的點(diǎn)會(huì)有大量人們搶購(gòu)車(chē)票。由于高并發(fā),導(dǎo)致服務(wù)癱瘓。

1.1 解決方案

內(nèi)存計(jì)算余票

異步交易系統(tǒng)(削峰方案)

數(shù)據(jù)庫(kù)進(jìn)行高可用搭建(讀寫(xiě)分離)

1.1.1 削峰解決方案

1. 削峰方案:

  • 對(duì)于瞬時(shí)流量我們最先想到的是中間件進(jìn)行削峰,把直接調(diào)用轉(zhuǎn)化為間接異步推送。中間隊(duì)列在一瞬間接受流量鋒,在另外一端平滑的將消息推送。

 

2. 答題:

在下單時(shí)候,我們需要答題。因?yàn)槊總€(gè)人的答題速度不一樣,錯(cuò)開(kāi)搶票時(shí)間。

3. 分時(shí)間段發(fā)放票:

將票分多個(gè)時(shí)間段進(jìn)行發(fā)放

1.1.2 數(shù)據(jù)同步方案架構(gòu)

 

  • 后臺(tái)管理員按照日期生成乘車(chē)計(jì)劃、座位信息、車(chē)次信息,并通過(guò)logstash將數(shù)據(jù)同步到ES和redis中。

二、用戶(hù)下單分析

用戶(hù)在下單時(shí)候,用戶(hù)經(jīng)歷下單、扣庫(kù)存、支付。在高并發(fā)場(chǎng)景下保證,車(chē)票不多買(mǎi)也不少賣(mài),且支付后車(chē)票真實(shí)有效。

2.1 對(duì)下單操作分析(異步下單的優(yōu)勢(shì))

1. 方案一

用戶(hù)在下單完,立馬扣除庫(kù)存,等待用戶(hù)支付。且創(chuàng)建訂單和扣除庫(kù)存是原子操作。能保證不超賣(mài)問(wèn)題。方案問(wèn)題:

  • 在極度并發(fā)請(qǐng)求下,每次創(chuàng)建訂單對(duì)內(nèi)存操作對(duì)性能影響很大。訂單數(shù)據(jù)需要保存到數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)壓力很大。如果很多人下了訂單,但是不支付。會(huì)導(dǎo)致很多票沒(méi)有賣(mài)掉。

2. 方案二

在極度并發(fā)場(chǎng)景下,庫(kù)存減為0時(shí)候,很多用戶(hù)搶到訂單卻不能支付。而且也不能避免數(shù)據(jù)的IO操作。

3. 方案三

  • 用戶(hù)選擇乘車(chē)計(jì)劃,點(diǎn)擊下單-->進(jìn)入下單服務(wù)集群中,--》判斷redis庫(kù)存是否充足,否(直接響應(yīng)票已售空)、是(預(yù)扣庫(kù)存)-》把下單信息發(fā)送給mq,es同步庫(kù)存信息-》如果用戶(hù)支付,訂單處理服務(wù)進(jìn)行訂單信息入庫(kù),并響應(yīng)成功信息。如果超時(shí)未支付,redis進(jìn)行庫(kù)存回退,es進(jìn)行庫(kù)存回退。

2.1 下單操作

2.1.1 nginx進(jìn)行限流配置

為了防止一些搶票助手發(fā)送無(wú)用請(qǐng)求,采用nginx進(jìn)行限流操作。

1. 限制訪問(wèn)頻率:limit_req_zone:單位時(shí)間內(nèi)請(qǐng)求數(shù),采用漏斗算法。

2. 限制并發(fā)連接數(shù):limit_conn_zone:同一時(shí)間的連接數(shù)。

2.1.2 下單流程

1. 訂單生成:

預(yù)扣庫(kù)存

找對(duì)應(yīng)日期對(duì)應(yīng)車(chē)次對(duì)應(yīng)座位類(lèi)型的乘車(chē)計(jì)劃庫(kù)存(站票,坐票,硬臥、軟臥等),進(jìn)行庫(kù)存扣減。

分配座位

遍歷所有指定座位類(lèi)型車(chē)廂的key(集合)。

遍歷集合獲取每個(gè)車(chē)廂的座位(集合)。遍歷集合獲取每一個(gè)座位對(duì)應(yīng)狀態(tài)。如果座位沒(méi)有售出,標(biāo)記座位并更改座位的狀態(tài)。

生成訂單

  • 在創(chuàng)建訂單時(shí)候,我們可以采用一個(gè)線(xiàn)程完成。且線(xiàn)程執(zhí)行完畢,我們要獲取線(xiàn)程的執(zhí)行結(jié)果,采用Callable執(zhí)行訂單創(chuàng)建。

在線(xiàn)程中創(chuàng)建訂單對(duì)象。

將指定日期的乘車(chē)計(jì)劃封裝到一個(gè)對(duì)象中。

生成訂單。

Redis排隊(duì)

采用 Redis 中的 ZSet 集合存儲(chǔ)排隊(duì)信息,使用:列車(chē)編號(hào) + 乘車(chē)日期 + 用戶(hù) id 作為 key,使用當(dāng)前系統(tǒng)時(shí)間的納秒值作為 value。

2. 同步ES庫(kù)存:

下單服務(wù)發(fā)送同步信息(乘車(chē)日期、座位性質(zhì)、列車(chē)車(chē)次)到mq中。es同步服務(wù)監(jiān)聽(tīng)mq,獲取發(fā)送信息。根據(jù)搜索條件查詢(xún)到數(shù)據(jù),并進(jìn)行庫(kù)存扣減。

3. 發(fā)送訂單數(shù)據(jù):

創(chuàng)建訂單和用戶(hù)信息,并設(shè)置交換機(jī)和隊(duì)列。發(fā)送訂單信息,發(fā)送完訂單數(shù)據(jù),跳轉(zhuǎn)到下單成功界面。下單成功界面調(diào)用排隊(duì)接口,顯示排隊(duì)信息。

2.1.3 訂單處理流程

1. 環(huán)境準(zhǔn)備:

因?yàn)橄聠?,?xiě)的操作遠(yuǎn)大于讀的操作,因此mysql采用雙主雙從搭建模式。

2. 保存訂單:

下單服務(wù)監(jiān)聽(tīng)mq,如果有訂單生成,對(duì)訂單信息進(jìn)行入庫(kù)。

3. 刪除排隊(duì)信息:

訂單保存成功后,刪除排隊(duì)信息。

4. 將下單結(jié)果通過(guò)websocket發(fā)送給客戶(hù)端:

保存完訂單數(shù)據(jù)以后,調(diào)用 WebSocketServer ,完成消息推送。

2.2 下單優(yōu)化

用戶(hù)已經(jīng)下單了,再次提交訂單是否扣除訂單?用戶(hù)雖然下單了但是一直沒(méi)有支付。預(yù)扣減庫(kù)存是否存在線(xiàn)程安全問(wèn)題。

2.2.1 預(yù)扣庫(kù)存優(yōu)化

當(dāng)該用戶(hù)已經(jīng)購(gòu)買(mǎi)了指定列車(chē)的火車(chē)票,那么我們就不能再進(jìn)行預(yù)扣庫(kù).

根據(jù)用戶(hù)信息和乘車(chē)計(jì)劃id查詢(xún)訂單信息,查詢(xún)到信息,不進(jìn)行庫(kù)存扣減。

2.2.2 庫(kù)存回退

1. 方案一(延遲隊(duì)列):

延遲隊(duì)列:消息發(fā)送后,特定時(shí)間后消費(fèi)者才能拿到消息進(jìn)行消費(fèi)。

2. 方案二(死信隊(duì)列):

死信隊(duì)列:一個(gè)消息在隊(duì)列中變成死信隊(duì)列之后,消息會(huì)被從新發(fā)送到另外一個(gè)交換機(jī)中,這個(gè)交換機(jī)就是死信隊(duì)列。一個(gè)消息成為死信隊(duì)列情況:

  • 消息被拒絕,并且設(shè)置 requeue 參數(shù)為 false
  • 消息過(guò)期
  • 隊(duì)列達(dá)到最大長(zhǎng)度

2.2.3 庫(kù)存安全性判斷(分布式鎖)

在進(jìn)行庫(kù)存扣減時(shí)候,加鎖。因?yàn)榭鄢龓?kù)存是多服務(wù),因此需要用分布式鎖來(lái)解決(mysql實(shí)現(xiàn),zookeeper實(shí)現(xiàn),redis實(shí)現(xiàn))。

 

責(zé)任編輯:姜華 來(lái)源: 花花和Java
相關(guān)推薦

2017-08-24 13:29:19

UDB高可用數(shù)據(jù)庫(kù)

2017-08-25 09:50:42

數(shù)據(jù)庫(kù)MySQL內(nèi)核優(yōu)化

2021-08-26 08:24:33

高并發(fā)秒殺系統(tǒng)

2016-11-28 09:08:43

java系統(tǒng)異步非阻塞

2024-09-23 08:03:13

2022-05-17 11:06:44

數(shù)據(jù)庫(kù)MySQL系統(tǒng)

2015-05-12 10:22:05

MySQL

2018-01-12 14:20:37

數(shù)據(jù)庫(kù)MySQL高可用架構(gòu)

2022-02-27 14:37:53

MySQL主備數(shù)據(jù)

2015-10-22 10:28:45

MySQL高可用方案

2019-08-27 15:56:44

MySQL 互聯(lián)網(wǎng)數(shù)據(jù)庫(kù)

2021-05-24 09:28:41

軟件開(kāi)發(fā) 技術(shù)

2023-03-01 22:28:15

Redis高可用

2015-10-21 12:58:58

keepalived集群Linux

2015-05-07 14:24:36

everRun

2012-04-24 09:30:57

淘寶開(kāi)發(fā)

2011-03-09 08:53:02

MySQL優(yōu)化集群

2022-09-29 15:24:15

MySQL數(shù)據(jù)庫(kù)高可用

2015-04-23 14:48:22

MYSQL

2014-07-11 09:43:34

MySQL集群
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)