對12306系統的服務以及售票系統有了進一步的了解:
其實,12306系統也相當於是電商系統,而且看起來商品就是票了。因為如果把一張票看成是乙個商品,那購票就類似於購買商品,然後每張票都有庫存,商品也有庫存的概念。但是如果我們仔細想想,會發現12306要複雜很多,因為我們無法預先確定好所有的票。
對於12306系統來說,他的使用者無異於是是兩者,其一就是我們這些進行出行購票普通使用者,另一方就是要售票的鐵道部。
對於傳統的電商系統來說,如果按照普通電商的思路,把票(站點區間)設計為商品(聚合根),然後為票設計庫存數量。我個人覺得是很糟糕的。因為一方面這種聚合根非常多,另一方面,即便列舉出來了,一次購票也一定會影響非常多其他聚合根的庫存數量(只要被部分或全部重疊的區間都受影響)。這樣的一次訂單處理的複雜度是難以評估的。而且這麼多聚合根的更新要在乙個事務裡,這不是為難資料庫嗎?而且,這種設計必然帶來大量的事務的併發衝突,很可能導致資料庫死鎖。總之,我認為這種是典型的由於領域模型的設計錯誤,導致併發衝突高、資料持久化落地困難。
對12306系統來說,車次具有一次出票的所有資訊,所以我們應該把出票的職責交給車次。我們應該知道,聚合設計有乙個原則,就是:聚合內強一致性,聚合之間最終一致性。對於系統售票,要產生一張票,其實要影響很多和這個票對應的直線相交的其他票的可用數量。因為所有的站點資訊都在車次聚合內部,所以車次聚合內部自然可以維護所有的原子區間,以及每個原子區間的可用票數(相當於是庫存數)。當乙個原子區間的可用票數為0的時候,意味著火車針對這個區間的票已經賣完了。所以,我們完全可以讓車次這個聚合根來保證出票時對所有原子區間的可用票數的更新的強一致性。對於車次聚合根來說,這很簡單,因為只是幾次簡單的記憶體操作而已,耗時可以忽略。一列火車假如有abcd四個站點,那原子區間就是3個。
根據訂單資訊,拿到出發地和目的地,然後獲取這段區間裡的所有的原子區間。然後嘗試將每個原子區間的可用票數減1,如果所有的原子區間都夠減,則購票成功;否則購票失敗,提示使用者該票已經賣完了。是不是很簡單呢?知道了出票的邏輯,那退票的邏輯也就很簡單了,就是把這個票的所有原子區間的可用票數加1就ok了。如果我們從線段的厚度的角度去考慮,那出票時,每個原子區間的厚度就是+1,退票時就是減一。就是相反的操作,但本質是一樣的。
在使用者進行購票付款的情況下,使用者有可能不去付款或者沒有在規定的時間內完成付款。那這種情況下,系統會自動釋放該使用者之前訂購的票。所以基於這樣的需求,我們在業務上需要支援業務級別的2pc。即先預扣庫存,也就是先佔住這張票一定時間(比如15分鐘),然後付款成功後再真實給你這張票,系統做真正的庫存修改。
在系統進行購票查詢的時候,對於12306來說,查詢的請求佔了80%,提交訂單的請求只佔20%。但查詢由於對資料沒有修改,所以我們完全可以使用分布式快取來實現。我們只需要精心設計好快取的key即可;快取key的多少要看成本,如果所有可能的查詢都設計對應的key,那時間複雜度為1,查詢效能自然高;但代價也大,因為key多了。如果想key少一點,那查詢的複雜度自然要上去一點。所以快取設計無非就是空間換時間的思路。然後,快取的更新無非就是:自動失效、定時更新、主動通知3種。通過cqrs架構,由於cq兩端是事件驅動的,當c端有任何狀態變化,都會產生對應的事件去通知q端,所以我們幾乎可以做到q端的準實時更新。
12306模型設計
傳統電商的思路 如果按照普通電商的思路,把票 站點區間 設計為商品 聚合根 然後為票設計庫存數量。我個人覺得是很糟糕的。因為一方面這種聚合根非常多,另一方面,即便列舉出來了,一次購票也一定會影響非常多其他聚合根的庫存數量 只要被部分或全部重疊的區間都受影響 這樣的一次訂單處理的複雜度是難以評估的。而...
IT四架構設計模型
按照頂層設計理論和方法的定義,資訊化頂層體系結構包括業務架構 資訊架構 應用架構和技術架構四大範疇。業務架構定義了整體業務能力以及各部門 各業務的協作關係,由業務要素模型表達整體業務能力,包括業務職能 業務布局和業務組合形態,由業務流程模型表達各部門 各業務的協作關係 資訊架構定義了全域性資訊資源組...
vuex 設計思路和實現
api概念的東西就不介紹了,如果還不了解vuex的應用,可以去檢視官方vuex文件 下面著重講解vuex的原理以及實現 vuex 設計思路 vuex是使用外掛程式機制開發的,vuex中的store本質就是沒有template的隱藏著的vue例項 在beforecreate混入vuexinit,vue...