12306模型設計

2022-08-02 15:00:37 字數 2029 閱讀 8616

傳統電商的思路

如果按照普通電商的思路,把票(站點區間)設計為商品(聚合根),然後為票設計庫存數量。我個人覺得是很糟糕的。因為一方面這種聚合根非常多,另一方面,即便列舉出來了,一次購票也一定會影響非常多其他聚合根的庫存數量(只要被部分或全部重疊的區間都受影響)。這樣的一次訂單處理的複雜度是難以評估的。而且這麼多聚合根的更新要在乙個事務裡,這不是為難資料庫嗎?而且,這種設計必然帶來大量的事務的併發衝突,很可能導致資料庫死鎖。總之,我認為這種是典型的由於領域模型的設計錯誤,導致併發衝突高、資料持久化落地困難。或者如果要解決併發問題,只能排隊單執行緒處理,但是仍然解決不了要在乙個事務裡修改大量聚合根的尷尬局面。聽說12306是採用了pivotal gemfire這種高大上的記憶體資料庫,我對這個不太了解。我不可想象要是不使用記憶體資料庫,他們要怎麼實現車次內的票之間的資料強一致性(就是保證所有**的票都是符合上面討論的業務規則的)?

我的思路

通過上面的分析我們知道,其實任何一次購票都是針對某個車次的。我們看看乙個車次包含了哪些資訊?乙個車次包括了:1)車次名稱,如g71;2)座位數,實際座位數會分型別,比如商務座20個,一等座200個;二等座500個;我們這裡為了簡化問題,可以暫時忽略型別,我認為這個型別不影響核心的模型的設計決策。需要格外注意的是:這裡的座位數不要理解為真實的物理座位數,很有可能比真實的座位數要少。因為我們不可能把乙個車次的所有座位都在網上通過12306來**,而是只**一部分,具體**多少,要由工作人員人工指定。3)經過的站點資訊(包括站點的id、站點名稱等),注意:車次還會記錄這些站點之間的順序關係;4)出發時間;看過grasp九大模式中的資訊專家模式的同學應該知道,將職責分配給擁有執行該職責所需資訊的類。我們這個場景,車次具有一次出票的所有資訊,所以我們應該把出票的職責交給車次。另外學過ddd的同學應該知道,聚合設計有乙個原則,就是:聚合內強一致性,聚合之間最終一致性。經過上面的分析,我們知道要產生一張票,其實要影響很多和這個票對應的直線相交的其他票的可用數量。因為所有的站點資訊都在車次聚合內部,所以車次聚合內部自然可以維護所有的原子區間,以及每個原子區間的可用票數(相當於是庫存數)。當乙個原子區間的可用票數為0的時候,意味著火車針對這個區間的票已經賣完了。所以,我們完全可以讓車次這個聚合根來保證出票時對所有原子區間的可用票數的更新的強一致性。對於車次聚合根來說,這很簡單,因為只是幾次簡單的記憶體操作而已,耗時可以忽略。一列火車假如有abcd四個站點,那原子區間就是3個。對於g71,則是16個。

然後基於上面的聚合設計,出票時扣減庫存的邏輯是:

根據訂單資訊,拿到出發地和目的地,然後獲取這段區間裡的所有的原子區間。然後嘗試將每個原子區間的可用票數減1,如果所有的原子區間都夠減,則購票成功;否則購票失敗,提示使用者該票已經賣完了。是不是很簡單呢?知道了出票的邏輯,那退票的邏輯也就很簡單了,就是把這個票的所有原子區間的可用票數加1就ok了。如果我們從線段的厚度的角度去考慮,那出票時,每個原子區間的厚度就是+1,退票時就是減一。就是相反的操作,但本質是一樣的。

所以,通過這樣的思路,我們將一次訂票的處理控制在了乙個聚合根裡,用聚合根內的強一致性的特性保證了訂票處理的強一致性,同時也保證了效能,免去了併發衝突的可能性。傳統電商那種把票單做類似商品的核心聚合根的設計,我當時第一眼看到就覺得不妥。因為這違背了ddd強調的強一致性應該由聚合根來保證、聚合根之間的最終一致性通過saga來保證的原則。

還有乙個很重要的概念我想說一下我的看法,就是座位和區間的關係。因為有些朋友和我講,考慮座位號的問題,雖然都能減1,座位號也必須是同乙個。我覺得座位是全域性共享的,和區段無關(也許我的理解完全有誤,請大家指正)。座位是乙個物理概念,乙個使用者成功購買了一張票後,座位就會少乙個,一張票唯一對應乙個座位,但是乙個座位有可能會對應多張票;而區間是乙個邏輯上的概念,區間的作用有兩個:1)表示票的出發地和目的地;2)記錄票的可用數額。如果區間能連通(即該區間內的每個原子區間的可用數額都大於0),則表示允許擁有乙個座位。所以,我覺得座位和票(區間)是兩個維度的概念。

模型分析總結:我認為票不是核心聚合根,票只是乙個計算的結果,乙個憑證而已,票本身沒有什麼邏輯;12306真正的核心模型應該是車次,車次具有出票的職責,並以強一致性的方式維護一次出票(或退票)時所有原子區間的可用票數。

****12306核心模型設計思路和架構設計

《12306核心模型設計思路和架構設計》閱讀心得

對12306系統的服務以及售票系統有了進一步的了解 其實,12306系統也相當於是電商系統,而且看起來商品就是票了。因為如果把一張票看成是乙個商品,那購票就類似於購買商品,然後每張票都有庫存,商品也有庫存的概念。但是如果我們仔細想想,會發現12306要複雜很多,因為我們無法預先確定好所有的票。對於1...

我設計的12306

feed系統和火車票售賣系統是2個高訪問高併發情況下具體很大挑戰的系統。在低訪問,低併發的情況下feed系統會變的非常簡單,資料模型和業務功能都比較容易設計和實現,主要的挑戰就剩如何面對層出不窮的敏感詞和花樣百出的廣告語。相比之下,火車票售賣系統在低併發時也很有趣,假設我是12306的架構師,我會如...

12306鐵道部客票系統設計交流

難得在上能看到案例設計討論,而且是關於12306售票系統的。於是我也來發表下的我一些感想,歡迎來吐槽!12306系統公升級了,但還是被吐槽了。這次國慶我沒買火車票,按照去年春節的購票經歷,我談談我的看法。什麼才是12306最需解決的問題?1 重大節假日前期,系統登陸難。2 搶票環節的併發處理能力。3...