偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

[[406897]]

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

在節(jié)假日和春節(jié)時候,火車票提前預售。在預售的點會有大量人們搶購車票。由于高并發(fā),導致服務癱瘓。

1.1 解決方案

內存計算余票

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

數(shù)據(jù)庫進行高可用搭建(讀寫分離)

1.1.1 削峰解決方案

1. 削峰方案:

  • 對于瞬時流量我們最先想到的是中間件進行削峰,把直接調用轉化為間接異步推送。中間隊列在一瞬間接受流量鋒,在另外一端平滑的將消息推送。

 

2. 答題:

在下單時候,我們需要答題。因為每個人的答題速度不一樣,錯開搶票時間。

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

將票分多個時間段進行發(fā)放

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

 

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

二、用戶下單分析

用戶在下單時候,用戶經歷下單、扣庫存、支付。在高并發(fā)場景下保證,車票不多買也不少賣,且支付后車票真實有效。

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

1. 方案一

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

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

2. 方案二

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

3. 方案三

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

2.1 下單操作

2.1.1 nginx進行限流配置

為了防止一些搶票助手發(fā)送無用請求,采用nginx進行限流操作。

1. 限制訪問頻率:limit_req_zone:單位時間內請求數(shù),采用漏斗算法。

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

2.1.2 下單流程

1. 訂單生成:

預扣庫存

找對應日期對應車次對應座位類型的乘車計劃庫存(站票,坐票,硬臥、軟臥等),進行庫存扣減。

分配座位

遍歷所有指定座位類型車廂的key(集合)。

遍歷集合獲取每個車廂的座位(集合)。遍歷集合獲取每一個座位對應狀態(tài)。如果座位沒有售出,標記座位并更改座位的狀態(tài)。

生成訂單

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

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

將指定日期的乘車計劃封裝到一個對象中。

生成訂單。

Redis排隊

采用 Redis 中的 ZSet 集合存儲排隊信息,使用:列車編號 + 乘車日期 + 用戶 id 作為 key,使用當前系統(tǒng)時間的納秒值作為 value。

2. 同步ES庫存:

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

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

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

2.1.3 訂單處理流程

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

因為下單,寫的操作遠大于讀的操作,因此mysql采用雙主雙從搭建模式。

2. 保存訂單:

下單服務監(jiān)聽mq,如果有訂單生成,對訂單信息進行入庫。

3. 刪除排隊信息:

訂單保存成功后,刪除排隊信息。

4. 將下單結果通過websocket發(fā)送給客戶端:

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

2.2 下單優(yōu)化

用戶已經下單了,再次提交訂單是否扣除訂單?用戶雖然下單了但是一直沒有支付。預扣減庫存是否存在線程安全問題。

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

當該用戶已經購買了指定列車的火車票,那么我們就不能再進行預扣庫.

根據(jù)用戶信息和乘車計劃id查詢訂單信息,查詢到信息,不進行庫存扣減。

2.2.2 庫存回退

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

延遲隊列:消息發(fā)送后,特定時間后消費者才能拿到消息進行消費。

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

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

  • 消息被拒絕,并且設置 requeue 參數(shù)為 false
  • 消息過期
  • 隊列達到最大長度

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

在進行庫存扣減時候,加鎖。因為扣除庫存是多服務,因此需要用分布式鎖來解決(mysql實現(xiàn),zookeeper實現(xiàn),redis實現(xiàn))。

 

責任編輯:姜華 來源: 花花和Java
相關推薦

2017-08-24 13:29:19

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

2021-08-26 08:24:33

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

2017-08-25 09:50:42

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

2016-11-28 09:08:43

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

2024-09-23 08:03:13

2025-10-09 08:14:25

12306官網APP服務器

2022-05-17 11:06:44

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

2015-05-12 10:22:05

MySQL

2015-10-22 10:28:45

MySQL高可用方案

2019-08-27 15:56:44

MySQL 互聯(lián)網數(shù)據(jù)庫

2021-05-24 09:28:41

軟件開發(fā) 技術

2022-02-27 14:37:53

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

2018-01-12 14:20:37

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

2023-03-01 22:28:15

Redis高可用

2015-10-21 12:58:58

keepalived集群Linux

2011-03-09 08:53:02

MySQL優(yōu)化集群

2015-05-07 14:24:36

everRun

2025-09-16 07:08:59

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

2015-04-23 14:48:22

MYSQL

2012-04-24 09:30:57

淘寶開發(fā)
點贊
收藏

51CTO技術棧公眾號