打车业务下单高并发解决方案
?
?
?
前言
在技術領域有一條準則,即不存在銀彈技術。在實際工作中,通常無法通過幾項簡單的技術組合就解決實際業務中各種場景下的復雜問題。雖然追求架構的簡單簡潔也是架構師的目標之一。但必須認識到架構的簡單簡潔和沒有銀彈技術是一對矛盾體。正是整個矛盾體在推進著技術的不斷進步。
本方案的目的在于拋磚引玉,介紹了 GTS TAM 團隊通過對實際技術服務工作中遇到的問題的思考,形成的一種解決方案。希望這個解決方案能夠對大家工作中的實際問題的解決起到啟發作用。如有興趣了解詳細細節,歡迎聯系阿里云 GTS TAM 團隊。
1. 行業背景
打車業務是出行行業的一個細分領域。這些年打車業務一直處于快速發展階段,除了不斷加大一二線城市發展,還不斷開拓三四線城市市場。8月25日滴滴出行的全球日訂單量首次突破了5000萬單。
打車行業的基本需求是撮合司機和乘客,達到滿足乘客出行需求的目的。打車系統核心是以定位、地圖等地理信息服務和訂單服務。除此以外,打車系統還包含支付、會員、計價等業務服務,容器、數據庫、緩存、消息隊列等云服務,以及人工智能、大數據、視頻監控等綜合性技術服務。
1.1 業務特點
打車行業的一個特點是其乘客端業務流量呈現明顯的潮汐波動。此外,還會因為節假日和惡劣天氣等原因導致業務流量波動,并且這種波動存在一定的不確定性。
?
1.2 技術挑戰
打車行業不易預測的業務峰值波動對包括訂單系統在內的打車業務核心系統的伸縮性,以及高并發能力、穩定性提出了比較高的要求。高并發能力和穩定性一定程度與伸縮性相關,業務系統的架構設計如何提供可伸縮的設計,自然也會提升系統的并發能力和穩定性。
應用從分層的角度來說通常分為接入層、應用層和數據層。其中,數據層的伸縮是重點和難點。目前阿里云 PolarDB 是數據庫領域最出色的彈性解決方案。但目前數據庫彈性伸縮還是只使用業務高峰時間和流量相對確定的場景。
2. 方案目標
本方案是聚焦打車業務的訂單場景的彈性伸縮解決方案。目的在于訂單這一打車業務核心系統能夠在無需人工操作的情況下,滿足不確定的業務高峰對打車訂單系統的沖擊,為客戶提供能滿足高并發且成本可控的訂單系統架構設計。
3. 詳細設計
為達到上述目標,本方案提供了如下架構設計。下圖是整體架構設計,左圖是傳統的訂單系統架構,分接入、應用和數據三層。右圖是彈性下單架構方案設計。在原有基礎上增加了兩層:前向訂單服務和訂單隊列。在這兩層之后,是訂單核心服務和訂單數據庫。
前向訂單服務將下單請求處理后,將數據寫入訂單隊列中即可返回。訂單隊列提供了高并發吞吐和較低的響應時間。訂單隊列由緩存和消息隊列組成,緩存以用戶維度保持最近的叫車狀態信息,而隊列則提供了高并發下單請求的持久化能力。
打車業務的下單場景能采用這種設計的原因是打車業務的訂單是以乘客 ID 為維度,單個乘客在同一時間段只有一個進行中訂單。整個流程的順序是先下單,再履約,最后支付。因為支付是在最后一步,而下單和履約的主體不同(下單的主體是乘客,履約的主體是司機),因此下單可異步化。
接下來將介紹新架構所引入的兩層新設計。
?
3.1 前端訂單應用層
前端訂單應用層的功能主要包括以下幾點:
- 功能一:基本校驗、風控及安全檢查
這一步是業務參數的校驗,以及風控安全方面的檢查。這一類操作的特點是可通過緩存等手段優化性能,并在不影響主要業務的情況下進行降級。將這些可緩存、可降級的操作前置到可彈性伸縮的應用層,有利于承載高并發的業務流量。
- 功能二:異步下單
因為新方案增加了訂單隊列層,因此需要前端訂單應用層實現異步下單的功能。這里涉及的操作主要是生成下單請求,將請求保存到緩存和隊列中,以及一些業務處理,比如根據加價金額及其它參數,控制下單隊列優先級。
這里需要注意的是這一步功能需要保障下單功能的冪等性、保證數據一致性和考慮請求亂序的問題。這些問題都是分布式系統研發過程中常見的問題,此處不再贅述。 - 功能三:限流降級
因為下單鏈路上增加了緩存和消息隊列,如果必須強依賴于這些服務,相較于原來的架構設計,可用性是下降的。因為新的訂單隊列層是為了實現提升系統在高并發場景下的彈性能力,因此不是必須的依賴。在 Redis 或消息隊列出現異常時,前端訂單服務需要能夠將請求繞過訂單隊列層,直接調用訂單核心服務,實現叫車下單功能。
3.2 訂單隊列層
如前所述,訂單隊列由緩存和消息隊列組成。緩存以乘客維度記錄最新的叫車狀態,消息隊列則持久化叫車請求。
- 接口冪等性
在具體實現中,方案建議先將叫車請求寫入消息隊列,再寫入緩存。原因是緩存中的數據表示叫車狀態,如果先寫入緩存,則無法通過其中的數據判斷是否寫入消息隊列成功。
- 請求順序性
請求異步化之后,請求的順序和實際處理的順序將無法保持一致。此時需要由業務系統實現上的設計保障新請求的處理結果不會被舊請求覆蓋。
- 數據一致性
緩存中的數據表示乘客的出行狀態,而乘客的出行狀態不只是來自于乘客的主動請求,而也會根據訂單狀態的不斷變化而變化。因此,緩存中的乘客出行狀態數據需要和后端訂單處理反映的實際狀態保持一致。
4. 技術架構
4.1 方案 PK
彈性應用層 + PolarDB 彈性數據庫 vs 本方案(訂單隊列異步下單)
應用架構的彈性伸縮方案的重點是數據層。數據庫采用 PolarDB,可以實現數據庫層的彈性伸縮。這個方案的優點是架構簡單,避免異步下單所帶來的研發復雜性和難度。缺點是需要人工執行伸縮,及時性不足。同時導致十幾秒(最多30秒以內)的業務中斷。因此較為適合業務高峰時間明確的場景。
訂單隊列異步下單方案的優點是彈性伸縮能力強,適應范圍廣。缺點是架構較為復雜,增加研發成本。
4.2 技術選型
4.2.1 彈性應用層:ACK + ECI
在上述的解決方案中,前端的應用層需要可彈性伸縮的計算服務給予支持。本方案建議采用 ACK + ECI 的組合。ACK 是阿里云 Kubernetes 服務(Alibaba Cloud Kubernetes)的縮寫,ECI 是彈性計算實例(Elastic Compute Instance)的縮寫,是一種 Serverless 技術,為包括容器服務在內上層計算資源提供無服務器的計算實例。
使用 ACK + ECI 可以構建彈性的應用層。ACK 本身也可以提供一定范圍的彈性伸縮能力,但 ACK 彈性伸縮分為 Pod 和 Node 彈性伸縮兩部分。Pod 運行在 Node 之上,但 Node 資源充足時,只需對 Pod 進行伸縮。當 Node 資源不足時,需要先擴容 Node,然后再創建新的 Pod。因此,單純使用 ACK 的伸縮特性的缺點就是時效性不足。同時還存在資源利用率不足的問題。
為解決 ACK 伸縮性的不足,本方案建議采用 ACK + ECI 的架構。ACK 通過 Virtual Node 與 ECI 連接。擴容時當 Node 資源不足時,會將擴容的 Pod 調度到 Virtual Node 上。 Virtual Node 通過 virtual-kubelet-autoscaler 將 Pod 擴容請求調度到 ECI 上。
?
?
4.2.2 訂單隊列:RocketMQ + Redis
本方案推薦采用 RocketMQ + Redis 實現訂單隊列。
RocketMQ 是阿里開源的消息隊列產品,與 Kafka 相比,雖然吞吐量不如 Kafka,但具備出色的穩定性和眾多適合在線業務的特性。因此,常選用 RocketMQ 作用在線業務的消息隊列,而 Kafka 通常適合大數據處理。
阿里云提供的 RocketMQ 分標準版和鉑金版兩種。雖然鉑金版價格較高,但處于穩定性的考慮,因此此方案推薦采用鉑金版作為線上訂單隊列中的消息隊列的實現技術。
阿里云提供了多種版本的 KV 存儲服務,兼容 Redis 協議。訂單隊列所需的 KV 存儲服務建議根據實際業務量評估規格,通常采用主從版即可。
4.3 部署架構
?
?
接入層和應用層容器服務雙可用區部署。MySQL 和 Redis 的主節點部署在其中一個可用區。
我們是阿里云智能全球技術服務-SRE團隊,我們致力成為一個以技術為基礎、面向服務、保障業務系統高可用的工程師團隊;提供專業、體系化的SRE服務,幫助廣大客戶更好地使用云、基于云構建更加穩定可靠的業務系統,提升業務穩定性。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的打车业务下单高并发解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 排队五小时才能吃上一口的Popeyes,
- 下一篇: 使用率激增 250%,这份报告再次将 S