1. 程式人生 > >雙十一談如何從零開始搭建大型機票交易平臺

雙十一談如何從零開始搭建大型機票交易平臺

導讀:從無到有構建一個大型交易平臺對工程師來說是很有挑戰的事情。在構建過程中會碰見各種技術或者非技術的問題,作為一個工程師又該如何處理這些問題,這是所有工程師都需要考慮的問題。知名旅遊網站負責交易平臺技術的小雄哥總結了自己的親身經歷,通過在高可用架構群的分享,給出了他自己的答案。

高可用架構讀者大家好,先做下簡單的自我介紹,我叫小雄哥,國內某大型旅遊網站的開發工程師,主要負責的是交易平臺的技術開發和管理。

背景介紹

進公司的原因是被同學和其他高管同事拉過來湊局,成立孵化平臺,當時正好缺少個技術負責搭平臺,所以合夥人都是有目的性的,這點很重要。

當時的市場,僅有一個類似的對手,而我們的實力,沒有技術平臺,沒有落地的需求,只有對機票事業部領導的承諾、模糊的想法IDEA,1個開發1個產品1個商務。

所以,大家首要目標就是:招開發、測試、商務、產品,快速落地。自然,我的任務就是:招人提升戰鬥力、學習業務、驗證和實現idea系統落地。

所以本次分享大部分是基於這三點。

開發組織

開發組織的情況

開發組織情況

公司文化很重要,很重要,很重要。

業務負責人從內部借到異地的開發:1 個做過兩年機票的,1 個酒店的,有幸得此兩人幫我快速瞭解公司內部的技術平臺。

之後,跟商務跑了家合作伙伴的公司,借到了 6 個 .net 的開發,其中 5 個人轉做 Java,1 個人轉去做產品,期間的借人過往就不描述了,很坎坷,非常感謝當時各位,大老遠過來參與封閉開發。基本上大家都擰在了一起,這樣開發資源不足的問題大致解決了,當然成本管理是公司領導考慮,這裡就不細說明。

但是新問題來了,產品只有想法沒出 PRD,開發這邊:語言不一致,水平不一(產品和開發不具備 B 端經驗)、技術團隊落戶深圳,人員穩定性隱患較大,人員投入困難,溝通不暢,向心力不足。

優先解決能力提升的問題,結合上圖是解決的辦法,是個迴圈漸進的過程,要堅持。

既然要做到堅持,就需要有約束有限制,以下是大家的約定。

開發組織約束

以上內容是組織管理的大部分內容。

下邊就是時間管理部分:

時間管理

結合產品的想法,列出所有模組的泳道圖、流程圖,核對每一個狀態機和操作的前驅後即。

進度彙報方面,採用的是每日晨會白板,每日早晚進度反饋群內分享,顏色標記進度等等方法。

對於預估錯誤和延期的處理方案是:小黑屋加班。回憶起來,上線前的幾個月是沒有周末的……

需求分析階段

由於前期產品能力不足、給出好幾十頁的 PRD 和頁面原型非常不好理解的前提下,幫助產品梳理需求,給出良好、乾淨的建議,也成功前期需求分解的重要工作,因為要確立開發方向,結果變成了現在的較為合理的樣子。

PRD 和原型轉換成流程圖:

PRD和原型轉換成流程圖

原型轉換成流程圖 原型轉換成流程圖

轉換成:

狀態機

等等類似各圖。模組流程的原型完了,進入狀態機:

時序圖

狀態機是採用無向圖的資料結構,根據交易流和狀態流向的模擬,給予產品 case 或形態有個很好的迴歸。

還有我們開發最熟悉的,時序圖輸出:

核心模組流圖

抱著這樣探索摸透的態度,我們開發梳理了這些,是為了保證模組負責人都能事前知道流程和技術功能。根據這樣具體的PRD,大家均能很大的明白業務到底要做什麼,流程是什麼。

當然弄了這麼多,缺點也很明顯,就是時間長了,重構多了,這些圖和表需要人維護。

推薦大家選擇時序圖,首先描述物件之間傳送訊息的時間順序顯示多個物件之間的動態協作。它可以表示用例的行為順序,當執行一個用例行為時,時序圖中的每條訊息對應了一個類操作或狀態機中引起轉換的觸發事件。

下面介紹,各大核心模組流圖:

我用字母和數字的組合,代表了當時上線的路徑。

上線的路徑

上線路徑

約票,最簡單的模組,為什麼要拿出來,因為當時我們的思路是跟滴滴打車學的,有采購叫單,供應來應。

類似各模組的流圖都要在前期需求分析階段出來,且模組負責人和對應開發都要熟知。

下面介紹,資料建模:

資料建模

有了這樣結構的好處:

  • 結合狀態機和操作,再根據交易流和資料流向的模擬,給予產品形態更好的迴歸,確保業務上無阻塞問題
  • 各模組互不干涉,從事務上給予更好的保證。

從資料量上,要有足夠的分析,預估上線的一個月內,日票量 1500 左右 即:15 * 7875 = 118125 條(資料庫記錄)。

產生一條主單訂單時,會增加:1 條訂單記錄,5 條工單,20 條工單回覆,10 條狀態變更,5 條支付和解凍記錄,4 條航班,9 條乘機人,約 45 條左右。.

與主訂單同比,子單約 40 條左右。每百主訂單會產生 5% 售後子單,即百條訂單 = 105 * 45 = 4725 (資料庫記錄) 。假定按出票率 60% 計算的話,百張票記錄 = 4725 / 0.6 = 7875,可保證 5 – 6 年的 150% 增長。

根據這個實際的業務量級考慮,所以我只做了分庫沒有分表。

以上的內容是是需求分析階段,大概兩週左右。

架構設計階段

到這個階段的時候,要分析要做的這個平臺的願景是什麼?這裡要結合公司對 B 端平臺的期望,最後重點是穩定、可靠、安全、靈活。

架構設計階段

由於發現有個老的執行比較久的政策管理和搜尋模組可以“借”來重構,那麼只需要考慮的其他幾個模組了,售前、售後、工單、運營平臺等。

找其他技術同學討論幾輪後,結合平臺期望,也最終確定了系統結構是怎樣的。

系統結構

因業務情況稍微解釋下,上邊的深藍色是入口和出口,左邊的黑色是公共技術,採用 dubbo 的 RPC(此處有坑),DAO 用的是 MyBatis,綠色部分代表其他部門提供支援。

這個系統結構,也是結合平臺期望來的,這個完了就要考慮工程結構了。

工程結構

從上到下,從左到右。採用複用的設計模式,個人認為較為合理的工程結構,也是目前我們工程制定的迭代任務制定的。

整體上完事了,下面到各模組的了,由於是業務獨特性,這裡插播下機票內部的業務流程。

先有供應商錄入航線和價格的東西,業內叫政策,錄入完了,採購商就能搜尋到,選擇適合的下單,支付和出票,這是售前,採購商拿到供應商提供的票號就可以讓 C 端使用者去做飛機了。

售後,就是退改簽、工單等,也是各大平臺的收入來源,與本次分享無關,不細說了。

機票搜尋

下面介紹,搜尋報價結構類圖:

報價結構類圖

簡單描述上圖,採購商查詢機票價格的條件是:出發目的地、時間之類的,業內叫 av。這部分資訊通過 OMS 同步模組將從代理商錄入的政策中航班等資訊作為索引放到 Solr 裡,匹配到了能取到政策 ID,再去 Redis 裡取政策詳情,找到反饋給採購商,當然其中有一些處理航司互動的東西。

生單系統

下面介紹,生單結構類圖:

生單結構類圖

生單結構類圖

簡單描述下,搜尋出報價,中間有個確認過程叫核價,就是最後看看是不是機票會變價,有變價是否接受。之後就進入生單。不同平臺的理解不一樣,有的平臺把支付之後叫生單。

由於不同航司,不同 GDS 標準,不同處理路徑,所以生單流程是均不一樣的。所以設計模式採用的是鏈式,這個比較成熟,當有新的流程,只需要在綠色加上對應的 handler,寫邏輯新增到 BizHandleBuilder 裡,做好規則即可,結合圖二進行理解。

支付系統

下面介紹,另外一個核心模組,支付類圖:

支付類圖

簡單描述下,生單之後,採購和供應都覺得 ok,採購商要支付。

B 端系統一般要支援這麼幾個功能:支援二次或改簽支付、靈活處理各種錯誤、支援中斷支付、繼續支付機制、明細檢視和匯出、管理員許可權支付、使用者級別鎖定、支援作廢正在支付中單子、營收和立減、財付通支付寶三方等。

要消化這些功能,所以要設計出:便於擴充套件,繼承指令引數拼接類,新增支付型別等抽象思想:

我這邊設計,採用藍色模組表示將支付流程統一處理,綠色代表指令執行拼接流程統一處理,橘黃色表示擴充套件部分,一般都是邏輯核心的地方。

比如,如果訂單要支援三次支付,那麼就可以多了一個 OrderThirdPayService。比如有個支付介面要適配,就要做個新的 XXX 實現指令拼接流程管理就好。

這裡給公司的支付中心點個贊,無論多晚,他們都有人都在陪著聯調。

以上列舉了兩、三個核心模組介紹,其他核心模組都類似設計。

模組設計的原則

簡約的理解,模組設計是要求這樣的,遵循依賴倒置單一原則。

模組設計原則

至少三層結構,遵循依賴倒置,且實現 service 都有各種方法提供,這也是給合作方很好的支援,想有各種方法都有。缺點是程式碼冗餘。

非同步化設計

下面就是邊邊角角的了,非同步化的設計:

非同步化設計

自己寫的,很基礎的,原因是為了都能看懂,也方便擴充套件,仍然是橘黃色的部分,隨便一個開發擴充套件使用都可以。當然是業務不出錯,對於難以保證資料的準確性,安全性不高,上下文 context switch 開銷,佔用本地還更多的資源等缺點,不 care。只要可以並列處理一些工作,從而減少一些不必要的等待時間,從能靈活滿足業務需要就行。

關於其他的架構設計,統一處理要求:

架構設計

簡單描述下說明下,因為是第一版,而且人員技術水平不太高的情況,所以,很多處理都是秉著簡易、好懂出發的。

  • 介面設計:這裡也考慮了複用機制,比如:訂單搜尋和訂單匯出,都是根據條件查詢給出結果的。利用了OOP根據不同訂單型別,來走不同路徑。
  • 依賴倒置:介面高層次的模組不依賴於低層次的模組實現。
  • 事務回滾: Service和Dao之間加一層 daohandle @Transactional xxxDaoHandle,這裡很有學問,由於表設計的很散,所以在這裡遇到很多問題。
  • 檔案儲存處理:比較好用的是因為路徑、資料夾可配,聽說 FastHFS 也不錯,也打算後續對比下。
  • 本地快取:採用 CacheBuilder 限制佇列,減低 Redis 壓力,響應時間優於 Redis。有過期時間。

按照這個架構設計,我們實現大概 2 個月左右的時間。

釋出之後

按照以上的需求和架構釋出後,基本上較穩定成長,期間也有外界的衝擊著,比如:孵化專案不被看好,中途人員流失,市場變動需要調整優先順序,公司整合等等問題,總之,你是負責人,問題抗住並要處理它。

希望這份分享能對大家有所幫助,如有問題可以在本文留言,也可以加講師微信 cpp_wazi 繼續交流。

文章出處:高可用架構(訂閱號ID:ArchNotes)

高可用架構