国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

馬蜂窩火車票系統(tǒng)服務(wù)化改造初探

Raaabbit / 1029人閱讀

摘要:為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務(wù)。現(xiàn)在,用戶在馬蜂窩也可以完成購買機票火車票等操作。第二階段架構(gòu)轉(zhuǎn)變及服務(wù)化初探從年開始,整個大交通業(yè)務(wù)開始從架構(gòu)向服務(wù)化演變。

交通方式是用戶旅行前要考慮的核心要素之一。為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務(wù)。現(xiàn)在,用戶在馬蜂窩也可以完成購買機票、火車票等操作。

與大多數(shù)業(yè)務(wù)系統(tǒng)相同,我們一樣經(jīng)歷著從無到有,再到快速發(fā)展的過程。本文將以火車票業(yè)務(wù)系統(tǒng)為例,主要從技術(shù)的角度,和大家分享在一個新興業(yè)務(wù)發(fā)展的不同階段背后,系統(tǒng)建設(shè)與架構(gòu)演變方面的一些經(jīng)驗。

第一階段:從無到有

在這個階段,快速支撐起業(yè)務(wù),填補業(yè)務(wù)空白是第一目標(biāo)。基于這樣的考慮,當(dāng)時的火車票業(yè)務(wù)從模式上選擇的是供應(yīng)商代購;從技術(shù)的角度需要優(yōu)先實現(xiàn)用戶在馬蜂窩 App 查詢車次余票信息、購票、支付,以及取消、退票退款等核心功能的開發(fā)。

圖1-核心功能與流程

技術(shù)架構(gòu)

綜合考慮項目目標(biāo)、時間、成本、人力等因素,當(dāng)時網(wǎng)站服務(wù)架構(gòu)我們選擇的是 LNMP(Linux 系統(tǒng)下 Nginx+MySQL+PHP)。整個系統(tǒng)從物理層劃分為訪問層 ( App,H5,PC 運營后臺),接入層 (Nginx),應(yīng)用層 (PHP 程序),中間件層 (MQ,ElasticSearch),存儲層 (MySQL,Redis)。

對外部系統(tǒng)依賴主要包括公司內(nèi)部支付、對賬、訂單中心等二方系統(tǒng),和外部供應(yīng)商系統(tǒng)。

圖 2-火車票系統(tǒng) V1.0 技術(shù)架構(gòu)

如圖所示,對外展現(xiàn)功能主要分為兩大塊,一塊是 C 端 App 和 H5,另外是運營后臺。二者分別經(jīng)過外網(wǎng) Nginx 和內(nèi)網(wǎng) Nginx 統(tǒng)一打到 php train 應(yīng)用上。程序內(nèi)部主要有四個入口,分別是:

供其他二方系統(tǒng)調(diào)用的 facade 模塊

運營后臺調(diào)用的 admin 模塊

處理 App 和 H5 請求的 train 核心模塊

處理外部供應(yīng)商回調(diào)模塊

四個入口會依賴于下層 modules 模塊實現(xiàn)各自功能。對外調(diào)用上分兩種情況,一種是調(diào)用二方系統(tǒng)的 facade 模塊滿足其公司內(nèi)部依賴;一種是調(diào)用外部供應(yīng)商。基礎(chǔ)設(shè)施上依賴于搜索、消息中間件、數(shù)據(jù)庫、緩存等。

這是典型的單體架構(gòu)模式,部署簡單,分層結(jié)構(gòu)清晰,容易快速實現(xiàn),可以滿足初期產(chǎn)品快速迭代的要求,而且建立在公司已經(jīng)比較成熟的 PHP 技術(shù)基礎(chǔ)之上,不必過多擔(dān)心穩(wěn)定性和可靠性的問題。

該架構(gòu)支撐火車票業(yè)務(wù)發(fā)展了將近一年的時間,簡單、易維護的架構(gòu)為火車票業(yè)務(wù)的快速發(fā)展做出了很大的貢獻。然而隨著業(yè)務(wù)的推進,單體架構(gòu)的缺陷逐漸暴露出來:

所有功能聚合在一起,代碼修改和重構(gòu)成本增大

研發(fā)團隊規(guī)模逐漸擴大,一個系統(tǒng)多人開發(fā)協(xié)作難度增加

交付效率低,變動范圍難以評估。在自動化測試機制不完善的情況下,易導(dǎo)致「修復(fù)越多,缺陷越多」的惡性循環(huán)

伸縮性差,只能橫向擴展,無法按模塊垂直擴展

可靠性差,一個 Bug 可能引起系統(tǒng)崩潰

阻礙技術(shù)創(chuàng)新,升級困難,牽一發(fā)而動全身

為了解決單體架構(gòu)所帶來的一系列問題,我們開始嘗試向微服務(wù)架構(gòu)演進,并將其作為后續(xù)系統(tǒng)建設(shè)的方向。

第二階段:架構(gòu)轉(zhuǎn)變及服務(wù)化初探

從 2018 年開始,整個大交通業(yè)務(wù)開始從 LNMP 架構(gòu)向服務(wù)化演變。

架構(gòu)轉(zhuǎn)變——從單體應(yīng)用到服務(wù)化

「工欲善其事,必先利其器」,首先簡單介紹一下大交通在實施服務(wù)化過程中積累的一些核心設(shè)施和組件。

我們最主要的轉(zhuǎn)變是將開發(fā)語言從 PHP 轉(zhuǎn)為 Java,因此技術(shù)選型主要圍繞 Java 生態(tài)圈來展開。

開發(fā)框架與組件

圖3-大交通基礎(chǔ)組件

如上圖所示,整體開發(fā)框架與組件從下到上分為四層。這里主要介紹最上層大交通業(yè)務(wù)場景下的封裝框架和組件層:

mlang:大交通內(nèi)部工具包

mes-client-starter:大交通 MES 技術(shù)埋點采集上報

dubbo-filter:對 Dubbo 調(diào)用的 tracing 追蹤

mratelimit:API 限流保護組件

deploy-starter:部署流量摘除工具

tul:統(tǒng)一登錄組件

cat-client:對 CAT 調(diào)用增強封裝的統(tǒng)一組件

基礎(chǔ)設(shè)施體系

服務(wù)化的實施離不開基礎(chǔ)設(shè)施體系的支持。在公司已有基礎(chǔ)之上,我們陸續(xù)建設(shè)了:

敏捷基礎(chǔ)設(shè)施:基于 Kubernetes 和 Docker

基礎(chǔ)設(shè)施監(jiān)控告警:Zabbix,Prometheus,Grafana

業(yè)務(wù)告警:基于 ES 日志,MES 埋點 + TAlarm

日志系統(tǒng) :ELK

CI/CD 系統(tǒng):基于 Gitlab+Jekins+Docker+Kubernetes

配置中心:Apollo

服務(wù)化支撐 :Springboot2.x+Dubbo

服務(wù)治理:Dubbo-admin,

灰度控制

TOMPS :大交通應(yīng)用管理平臺

MPC 消息中心:基于 RocketMQ

定時任務(wù):基于 Elastic-Job

APM 系統(tǒng) :PinPoint,CAT

PHP 和 Java 雙向互通支持

如上所述,初步構(gòu)筑了較為完整的 DevOps + 微服務(wù)開發(fā)體系。整體架構(gòu)如下:

圖4-大交通基礎(chǔ)設(shè)施體系

從上至下依次分為:

訪問層——目前有 App,H5 和微信小程序;

接入層——走公司公共的 Nginx,OpenResty;

業(yè)務(wù)層的應(yīng)用——包括無線 API,Dubbo 服務(wù),消

消息中心和定時任務(wù)——部署在 Kubernetes+Docker 中

中間件層——包括 ElasticSearch,RocketMQ 等

存儲層——MySQL,Redis,F(xiàn)astDFS,HBase 等

此外,外圍支撐系統(tǒng)包括 CI/CD、服務(wù)治理與配置、APM 系統(tǒng)、日志系統(tǒng)、監(jiān)控告警系統(tǒng)。

CI/CD?系統(tǒng)

CI 基于 Sonar + Maven(依賴檢查,版本檢查,編譯打包) + Jekins

CD 基于 Jekins+Docker+Kubernetes

我們目前還沒有放開 Prod 的 OPS 權(quán)限給開發(fā),計劃在新版 CD 系統(tǒng)中會逐步開放。

圖5-CI/CD 體系

服務(wù)化框架?Dubbo

我們選擇 Dubbo 作為分布式微服務(wù)框架,主要有以下因素考慮:

成熟的高性能分布式框架。目前很多公司都在使用,已經(jīng)經(jīng)受住各方面性能考驗,比較穩(wěn)定;

可以和 Spring 框架無縫集成。我們的架構(gòu)正是基于 Spring 搭建,并且接入 Dubbo 時可以做到代碼無侵入,接入也非常方便;

具備服務(wù)注冊、發(fā)現(xiàn)、路由、負(fù)載均衡、服務(wù)降級、權(quán)重調(diào)節(jié)等能力;

代碼開源。可以根據(jù)需求進行個性化定制,擴展功能,進行自研發(fā)

圖 6-Dubbo 架構(gòu)

除了保持和 Dubbo 官方以及社區(qū)的密切聯(lián)系外,我們也在不斷對 Dubbo 進行增強與改進,比如基于 dubbo-fitler 的日志追蹤,基于大交通統(tǒng)一應(yīng)用管理中心的 Dubbo 統(tǒng)一配置管理、服務(wù)治理體系建設(shè)等。

服務(wù)化初探——搶票系統(tǒng)

向服務(wù)化的演進決不能是一個大躍進運動,那樣只會把應(yīng)用拆分得七零八落,最終不但大大增加運維成本,而且看不到收益。

為了保證整個系統(tǒng)的服務(wù)化演進過程更加平滑,我們首先選擇了搶票系統(tǒng)進行實踐探索。搶票是火車票業(yè)務(wù)中的一個重要版塊,而且搶票業(yè)務(wù)相對獨立,與已有的 PHP 電子票業(yè)務(wù)沖突較少,是我們實施服務(wù)化的較佳場景。

在對搶票系統(tǒng)進行服務(wù)拆分和設(shè)計時,我們積累了一些心得和經(jīng)驗,主要和大家分享以下幾點。

功能與邊界

簡單來說,搶票就是實現(xiàn)用戶提前下?lián)屍眴危到y(tǒng)在正式開售之后不斷嘗試為用戶購票的過程。從本質(zhì)上來說,搶票是一種手段,通過不斷檢測所選日期和車次的余票信息,以在有余票時為用戶發(fā)起占座為目的。至于占座成功以后的處理,和正常電子票是沒有什么區(qū)別的。理解了這個過程之后,在盡量不改動原有 PHP 系統(tǒng)的前提下,我們這樣劃分它們之間的功能邊界:

圖7-搶票功能劃分

也就是說,用戶下?lián)屍眴沃Ц冻晒Γ龘屍闭甲晒螅罄m(xù)出票的事情我們會交給 PHP 電子票系統(tǒng)去完成。同理,在搶票的逆向方面,只需實現(xiàn)「未搶到票全額退」以及「搶到票的差額退」功能,已出票的線上退和線下退票都由 PHP 系統(tǒng)完成,這就在很大程度上減少了搶票的開發(fā)任務(wù)。

服務(wù)設(shè)計

服務(wù)的設(shè)計原則包括隔離、自治性、單一職責(zé)、有界上下文、異步通信、獨立部署等。其他部分都比較容易把控,而有界上下文通俗來說反應(yīng)的就是服務(wù)的粒度問題,這也是做服務(wù)拆分繞不過去的話題。粒度太大會導(dǎo)致和單體架構(gòu)類似的問題,粒度太細(xì)又會受制于業(yè)務(wù)和團隊規(guī)模。結(jié)合實際情況,我們對搶票系統(tǒng)從兩個維度進行拆分:

1. 從業(yè)務(wù)角度系統(tǒng)劃分為供應(yīng)商服務(wù) (同步和推送)、正向交易服務(wù)、逆向交易服務(wù)、活動服務(wù)。

圖8-搶票服務(wù)設(shè)計

正向交易服務(wù):包括用戶下?lián)屍眴巍⒅Ц丁⑷∠⒊銎薄⒉樵儭⑼ㄖ裙δ?/p>

逆向交易服務(wù):包括逆向訂單、退票、退款、查詢、通知等

供應(yīng)側(cè):去請求資源方完成對應(yīng)業(yè)務(wù)操作、下?lián)屍眴巍⑷∠⒄甲⒊銎钡?/p>

活動服務(wù):包括日常活動、分享、活動排名統(tǒng)計等

2. 從系統(tǒng)層級分為前端 H5 層前后分離、API 接入層、RPC 服務(wù)層,和 PHP 之間的橋接層、異步消息處理、定時任務(wù)、供應(yīng)商對外調(diào)用和推送網(wǎng)關(guān)。

圖9-搶票系統(tǒng)分層

展示層:H5 和小程序,前后端分離

API 層:對 H5 和小程序提供的統(tǒng)一 API 入口網(wǎng)關(guān),負(fù)責(zé)對后臺服務(wù)的聚合,以 HTTP REST 風(fēng)格對外暴露

服務(wù)層:包括上節(jié)所提到的業(yè)務(wù)服務(wù),對外提供 RPC 服務(wù)

橋接層:包括調(diào)用 PHP 的代理服務(wù),對 Java 側(cè)提供 Dubbo RPC 服務(wù),以 HTTP 形式調(diào)用統(tǒng)一的 PHP 內(nèi)部網(wǎng)關(guān);對 PHP 提供的統(tǒng)一 GW,PHP 以 HTTP 形式通過 GW 來調(diào)用 Java 服務(wù)

消息層:異步的消息處理程序,包括訂單狀態(tài)變更通知,優(yōu)惠券等處理

定時任務(wù)層:提供各種補償任務(wù),或者業(yè)務(wù)輪詢處理

數(shù)據(jù)要素

對于交易系統(tǒng)而言,不管是用何種語言,何種架構(gòu),要考慮的最核心部分終歸是數(shù)據(jù)。數(shù)據(jù)結(jié)構(gòu)基本反應(yīng)了業(yè)務(wù)模型,也左右著程序的設(shè)計、開發(fā)、擴展與升級維護。我們簡單梳理一下?lián)屍毕到y(tǒng)所涉及的核心數(shù)據(jù)表:

1. 創(chuàng)單環(huán)節(jié):用戶選擇車次進入填單頁以后,要選擇乘車人、添加聯(lián)系人,所以首先會涉及到乘車人表,這塊復(fù)用的 PHP 電子票功能

2. 用戶提交創(chuàng)單申請后,將會涉及到以下數(shù)據(jù)表:

訂單快照表——首先將用戶的創(chuàng)單請求要素存儲起來

搶票訂單表 (order):為用戶創(chuàng)建搶票單

區(qū)段表(segment):用于一個訂單中可能存在的連續(xù)乘車而產(chǎn)生的多個車次情況 (類似機票航段)

乘車人表 (passenger):搶票單中包含乘車人信息

活動表 (activity):反映訂單中可能包含的活動信息

物品表 (item):反映包含的車票,保險等信息

履約表:用戶購買車票、保險后,最終會做票號回填,我們也叫票號信息表

3. 產(chǎn)生占座結(jié)果后:用戶占座失敗涉及全額退款,占座成功可能涉及差額退款,因此我們會有退票訂單表 (refund_order);雖然只涉及到退款,但同樣會有 refund_item 表來記錄退款明細(xì)。

訂單狀態(tài)

訂單系統(tǒng)的核心要點是訂單狀態(tài)的定義和流轉(zhuǎn),這兩個要素貫穿著整個訂單的生命周期。

我們從之前的系統(tǒng)經(jīng)驗中總結(jié)出兩大痛點,一是訂單狀態(tài)定義復(fù)雜,我們試圖用一個狀態(tài)字段來打通前臺展示和后端邏輯處理,結(jié)果導(dǎo)致單一訂單狀態(tài)多達 18 種;二是狀態(tài)流轉(zhuǎn)邏輯復(fù)雜,流轉(zhuǎn)的前置因素判斷和后置方向上太多的 if else 判斷,代碼維護成本高。

因此,我們采用有限狀態(tài)機來梳理搶票正向訂單的狀態(tài)和狀態(tài)流轉(zhuǎn),關(guān)于狀態(tài)機的應(yīng)用,可以參照之前發(fā)過的一篇文章《狀態(tài)機在馬蜂窩機票交易系統(tǒng)中的應(yīng)用與優(yōu)化》,下圖是搶票訂單的狀態(tài)流轉(zhuǎn)圖:

圖10-搶票訂單狀態(tài)流轉(zhuǎn)

我們將狀態(tài)分為訂單狀態(tài)和支付狀態(tài),通過事件機制來推進狀態(tài)的流轉(zhuǎn)。到達目標(biāo)態(tài)有兩個前提:一是原狀態(tài),二是觸發(fā)事件。狀態(tài)按照預(yù)設(shè)的條件和路線進行流轉(zhuǎn),將業(yè)務(wù)邏輯的執(zhí)行和事件觸發(fā)與狀態(tài)流轉(zhuǎn)拆分開,達到解耦和便于擴展維護的目的。

如上圖所示,將訂單狀態(tài)定義為:初始化→下單成功→交易成功→關(guān)閉。給支付狀態(tài)定義為:初始化→待支付→已支付→關(guān)閉。以正常 case 來說,用戶下單成功后,會進入下單成功和待支付;用戶通過收銀臺支付后,訂單狀態(tài)不變,支付狀態(tài)為已支付;之后系統(tǒng)會開始幫用戶占座,占座成功以后,訂單會進入交易成功,支付狀態(tài)不變。

如果僅僅是上面的雙狀態(tài),那么業(yè)務(wù)程序執(zhí)行倒是簡單了,但無法滿足前臺給用戶豐富的單一狀態(tài)展示,因此我們還會記錄關(guān)單原因。關(guān)單原因目前有 7 種:未關(guān)閉、創(chuàng)單失敗、用戶取消、支付超時、運營關(guān)單、訂單過期、搶票失敗。我們會根據(jù)訂單狀態(tài)、支付狀態(tài)、關(guān)單原因,計算出一個訂單對外展示狀態(tài)。

冪等性設(shè)計

所謂冪等性,是指對一個接口進行一次調(diào)用和多次調(diào)用,產(chǎn)生的結(jié)果應(yīng)該是一致的。冪等性是系統(tǒng)設(shè)計中高可用和容錯性的一個有效保證,并不只存在于分布式系統(tǒng)中。我們知道,在 HTTP 中,GET 接口是天生冪等的,多次執(zhí)行一個 GET?操作,并不會對系統(tǒng)數(shù)據(jù)產(chǎn)生不一致的影響,但是 POST,PUT,DELETE 如果重復(fù)調(diào)用,就可能產(chǎn)生不一致的結(jié)果。

具體到我們的訂單狀態(tài)來說,前面提到狀態(tài)機的流轉(zhuǎn)是需要事件觸發(fā)的,目前搶票正向的觸發(fā)事件有:下單成功、支付成功、占座成功、關(guān)閉訂單、關(guān)閉支付單等等。我們的事件一般由用戶操作或者異步消息推送觸發(fā),其中任意一種都無法避免產(chǎn)生重復(fù)請求的可能。以占座成功事件來說,除了修改自身表狀態(tài),還要向訂單中心同步狀態(tài),向 PHP 電子票同步訂單信息,如果不做冪等性控制,后果是非常嚴(yán)重的。

保證冪等性的方法有很多,以占座消息為例,我們有兩個措施來保證冪等:

占座消息都帶有協(xié)議約束的唯一 serialNo,推送服務(wù)可以判斷該消息是否已被正常處理。

業(yè)務(wù)側(cè)的修改實現(xiàn) CAS(Compare And Swap),簡單來說就是數(shù)據(jù)庫樂觀鎖,如 update order set order_status = 2 where order_id = 『1234" and order_status = 1 and pay_status = 2 。

小結(jié)

服務(wù)化的實施具備一定的成本,需要人員和基礎(chǔ)設(shè)施都有一定的基礎(chǔ)。初始階段,從相對獨立的新業(yè)務(wù)著手,做好和舊系統(tǒng)的融合復(fù)用,能較快的獲取成果。搶票系統(tǒng)在不到一個月的時間內(nèi)完成產(chǎn)品設(shè)計,開發(fā)聯(lián)調(diào),測試上線,也很好地印證了這一點。

第三階段:服務(wù)化推進和系統(tǒng)能力提升

搶票系統(tǒng)建設(shè)的完成,代表我們邁出了一小步,也只是邁出了一小步,畢竟搶票是周期性的業(yè)務(wù)。更多的時間里,電子票是我們業(yè)務(wù)量的主要支撐。在新老系統(tǒng)的并行期,主要有以下痛點:

原有電子票系統(tǒng)由于當(dāng)時因素影響,與特定供應(yīng)商綁定緊密,受供應(yīng)商制約較大;

由于和搶票系統(tǒng)及大交通其他系統(tǒng)之間的兼容成本較高,導(dǎo)致我們統(tǒng)一鏈路追蹤、環(huán)境隔離、監(jiān)控告警等工作實施難度很大;

PHP 和 Java 橋接層承接太多業(yè)務(wù),性能無法保證

因此,卸下歷史包袱,盡快完成舊系統(tǒng)的服務(wù)化遷移,統(tǒng)一技術(shù)棧,使主要業(yè)務(wù)得到更加有力的系統(tǒng)支撐,是我們接下來的目標(biāo)。

與業(yè)務(wù)同行:電子票流程改造

我們希望通過對電子票流程的改造,重塑之前應(yīng)急模式下建立的火車票項目,最終實現(xiàn)以下幾個目標(biāo):

建立馬蜂窩火車票的業(yè)務(wù)規(guī)則,改變之前業(yè)務(wù)功能和流程上受制于供應(yīng)側(cè)規(guī)則的局面;

完善用戶體驗和功能,增加在線選座功能,優(yōu)化搜索下單流程,優(yōu)化退款速度,提升用戶體驗;

提升數(shù)據(jù)指標(biāo)和穩(wěn)定性,引入新的供應(yīng)側(cè)服務(wù),提高可靠性;供應(yīng)商分單體系,提升占座成功率和出票率;

技術(shù)上完成到 Java 服務(wù)化的遷移,為后續(xù)業(yè)務(wù)打下基礎(chǔ)

我們要完成的不僅是技術(shù)上的重構(gòu),而是結(jié)合新的業(yè)務(wù)訴求,去不斷豐富新的系統(tǒng),力求達到業(yè)務(wù)和技術(shù)的目標(biāo)一致性,因此我們將服務(wù)化遷移和業(yè)務(wù)系統(tǒng)建設(shè)結(jié)合在一起推進。下圖是電子票流程改造后火車票整體架構(gòu):

圖11-電子票改造后的火車票架構(gòu)

圖中淺藍(lán)色部分為搶票期間已經(jīng)建好的功能,深藍(lán)色模塊為電子票流程改造新加入的部分。除了和搶票系統(tǒng)類似的供應(yīng)商接入、正向交易、逆向交易以外,還包括搜索與基礎(chǔ)數(shù)據(jù)系統(tǒng),在供應(yīng)側(cè)也增加了電子票的業(yè)務(wù)功能。同時我們新的運營后臺也已經(jīng)建立,保證了運營支撐的延續(xù)性。

項目實施過程中,除了搶票所說的一些問題之外,也著重解決以下幾個問題。

搜索優(yōu)化

先來看用戶一次站站搜索可能穿過的系統(tǒng):

圖12-站站查詢調(diào)用流程

請求先到 twl api 層,再到 tsearch 查詢服務(wù),tsearch 到 tjs 接入服務(wù)再到供應(yīng)側(cè),整個調(diào)用鏈路還是比較長的,如果每次調(diào)用都是全鏈路調(diào)用,那么結(jié)果是不太樂觀的。因此 tsearch 對于查詢結(jié)果有 redis 緩存,緩存也是縮短鏈路、提高性能的關(guān)鍵。站站查詢要緩存有幾個難點:

對于數(shù)據(jù)實時性要求很高。核心是余票數(shù)量,如果數(shù)據(jù)不實時,那么用戶再下單占座成功率會很低

數(shù)據(jù)比較分散。比如出發(fā)站,到達站,出發(fā)日期,緩存命中率不高

供應(yīng)側(cè)接口不穩(wěn)定。平均在 1000ms 以上

綜合以上因素考慮,我們設(shè)計 tsearch 站站搜索流程如下:

圖13-搜索設(shè)計流程

如圖所示,首先對于一個查詢條件,我們會緩存多個渠道的結(jié)果,一方面是因為要去對比哪個渠道結(jié)果更加準(zhǔn)確,另一方面可以增加系統(tǒng)可靠性和緩存命中率。

我們將 Redis 的過期時間設(shè)為 10min,對緩存結(jié)果定義的有效期為 10s,首先取有效;如果有效為空,則取失效;如果失效也為空,則同步限時 3s 去調(diào)用渠道獲取,同時將失效和不存在的緩存渠道交給異步任務(wù)去更新。需要注意通過分布式鎖來防止并發(fā)更新一個渠道結(jié)果。最終的緩存結(jié)果如下:

緩存的命中率會在 96% 以上,RT 平均在 500ms 左右,能夠在保證用戶體驗良好的同時,做到及時的數(shù)據(jù)更新。

消息的消費

我們有大量業(yè)務(wù)是通過異步消息方式來處理的,比如訂單狀態(tài)變更消息、占座通知消息、支付消息等。除了正常的消息消費以外,還有一些特殊的場景,如順序消費、事務(wù)消費、重復(fù)消費等,主要基于 RocketMQ 來實現(xiàn)。

順序消費

主要應(yīng)用于對消息有先后依賴的場景,比如創(chuàng)單消息必須先于占座消息被處理。RocketMQ 本身支持消息順序消費,我們基于它來實現(xiàn)這種業(yè)務(wù)場景。從原理上來說也很簡單,RocketMQ 限定生產(chǎn)者只能將消息發(fā)往一個隊列,同時限定消費端只能有一個線程來讀取,這樣全局單隊列,單消費者就保證了消息的順序消費。

重復(fù)消費

RocketMQ 保障的是 At Least Once,并不能保證 Exactly Only Once,前面搶票我們也提過,一是通過要求業(yè)務(wù)側(cè)保持冪等性,另外通過數(shù)據(jù)庫表 message_produce_record 和 message_consume_record 來保證精準(zhǔn)一次投遞和消費結(jié)果確認(rèn)。

事務(wù)消費

基于 RocketMQ 的事務(wù)消息功能。它支持二階段提交,會先發(fā)送一條預(yù)處理消息,然后回調(diào)執(zhí)行本地事務(wù),最終提交或者回滾,幫助保證修改數(shù)據(jù)庫的信息和發(fā)送異步消息的一致。

灰度運行

殲十戰(zhàn)機的總設(shè)計師曾說過一句話:「造一架飛機不是最難的,難的是讓它上天」,對我們來說同樣如此。3 月是春游季的高峰,業(yè)務(wù)量與日俱增,在此期間完成系統(tǒng)重大切換,我們需要完備的方案來保障業(yè)務(wù)的順利切換。

方案設(shè)計

灰度分為白名單部分和百分比灰度部分,我們首先在內(nèi)部進行白名單灰度,穩(wěn)定后進入 20% 流量灰度期。

灰度的核心是入口問題,由于本次前端也進行了完整改版,因此我們從站站搜索入口將用戶引入到不同的頁面,用戶分別會在新舊系統(tǒng)中完成業(yè)務(wù)。

圖14-灰度運行方案

搜索下單流程

App 在站站搜索入口調(diào)用灰度接口獲取跳轉(zhuǎn)地址,實現(xiàn)入口分流。

圖15-搜索下單分流

效果對比

近期規(guī)劃

我們只是初步實現(xiàn)了服務(wù)化在火車票業(yè)務(wù)線的落地實施,與此同時,還有一些事情是未來我們要去持續(xù)推進和改進的:

1. 服務(wù)粒度細(xì)化:目前的服務(wù)粒度仍然比較粗糙。隨著功能的不斷增多,粒度的細(xì)化是我們要去改進的重點,比如將交易服務(wù)拆分為訂單查詢服務(wù),創(chuàng)單服務(wù),處理占座的服務(wù)和處理出票的服務(wù)。這也是 DevOps 的必然趨勢。細(xì)粒度的服務(wù),才能最大限度滿足我們快速開發(fā)、快速部署,以及風(fēng)險可控的要求。

2. 服務(wù)資源隔離:只在服務(wù)粒度實現(xiàn)隔離是不夠的。DB 隔離、緩存隔離、MQ 隔離也非常必要。隨著系統(tǒng)的不斷擴展與數(shù)據(jù)量的增長,對資源進行細(xì)粒度的隔離是另一大重點。

3. 灰度多版本發(fā)布:目前我們的灰度策略只能支持新老版本的并行,未來除了會進行多版本并行驗證,還要結(jié)合業(yè)務(wù)定制化需求,使灰度策略更加靈活。

寫在最后

業(yè)務(wù)的發(fā)展離不開技術(shù)的發(fā)展,同樣,技術(shù)的發(fā)展也要充分考慮當(dāng)時場景下的業(yè)務(wù)現(xiàn)狀和條件,二者相輔相成。比起設(shè)計不足而言,我們更要規(guī)避過度設(shè)計。

技術(shù)架構(gòu)是演變出來的,不是一開始設(shè)計出來的。我們需要根據(jù)業(yè)務(wù)發(fā)展規(guī)律,將長期技術(shù)方案進行階段性分解,逐步達成目標(biāo)。同時,也要考慮服務(wù)化會帶來很多新問題,如復(fù)雜度驟增、業(yè)務(wù)拆分、一致性、服務(wù)粒度、鏈路過長、冪等性、性能等等。

比服務(wù)支撐更難的是服務(wù)治理,這也是我們大家要深入思考和去做的事情。

本文作者:李戰(zhàn)平,馬蜂窩大交通業(yè)務(wù)研發(fā)技術(shù)專家。

(題圖來源:網(wǎng)絡(luò))

關(guān)注馬蜂窩技術(shù),找到更多你想要的內(nèi)容

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/31336.html

相關(guān)文章

  • 馬蜂火車系統(tǒng)務(wù)化改造初探

    摘要:為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務(wù)。現(xiàn)在,用戶在馬蜂窩也可以完成購買機票火車票等操作。第二階段架構(gòu)轉(zhuǎn)變及服務(wù)化初探從年開始,整個大交通業(yè)務(wù)開始從架構(gòu)向服務(wù)化演變。 交通方式是用戶旅行前要考慮的核心要素之一。為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務(wù)。現(xiàn)在,用戶在馬蜂窩也可以完成購買機票、火車票等操作。 與大多數(shù)業(yè)務(wù)系統(tǒng)相同,我們一樣經(jīng)歷著從無到有...

    doodlewind 評論0 收藏0
  • 馬蜂大交通業(yè)務(wù)質(zhì)量體系建設(shè)初步實踐

    摘要:大交通研發(fā)質(zhì)量體系建設(shè)為了幫助用戶更好地完成消費決策閉環(huán),馬蜂窩上線了大交通業(yè)務(wù),為用戶提供購買機票火車票等服務(wù)。 質(zhì)量是決定產(chǎn)品能否成功、企業(yè)能否持續(xù)發(fā)展的關(guān)鍵因素之一。如何做好質(zhì)量體系建設(shè),這是個比較大的話題,包含的范圍很廣,也沒有固定的衡量標(biāo)準(zhǔn)。 打開一個互聯(lián)網(wǎng)公司招聘網(wǎng)站,搜索「測試工程師」崗位時,你會發(fā)現(xiàn)幾乎全部 JD 都包含一條要求「建設(shè)或者參與建設(shè)所負(fù)責(zé)業(yè)務(wù)的質(zhì)量體系」。...

    Ilikewhite 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<