自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為業(yè)務(wù)系統(tǒng)賦能,攜程機(jī)票最終行程系統(tǒng)架構(gòu)演進(jìn)之路

開發(fā)
攜程機(jī)票訂單系統(tǒng)是由多個業(yè)務(wù)子系統(tǒng)組成,包括出票、改簽、航變等等,獲取訂單行程信息復(fù)雜度較高。

作者簡介

Stephen,攜程資深后端開發(fā)工程師,專注新技術(shù)挖掘,持續(xù)推動業(yè)務(wù)創(chuàng)新

Scott ,攜程資深研發(fā)經(jīng)理,負(fù)責(zé)訂單系統(tǒng)架構(gòu)升級和優(yōu)化

一、背景

攜程機(jī)票訂單系統(tǒng)是由多個業(yè)務(wù)子系統(tǒng)組成,包括出票、改簽、航變等等,獲取訂單行程信息復(fù)雜度較高。

例如:用戶預(yù)訂了一個包含了2個乘客的機(jī)票訂單,該訂單發(fā)生了航變,其中用戶A選擇了退票,用戶B選擇了改簽。

業(yè)務(wù)系統(tǒng)需要獲得該訂單最新的行程信息以及行程變化軌跡,以進(jìn)行展示和進(jìn)一步處理。

圖片

上述例子用戶的最新行程信息為:

  • 乘客1:航班號9C888,SHA-PEK,已退票
  • 乘客2:航班號9C999,SHA-PEK,已改簽

歷史的系統(tǒng)設(shè)計需要通過API對各業(yè)務(wù)子系統(tǒng)的數(shù)據(jù)進(jìn)行實(shí)時的聚合和計算,如果要獲取上述例子的最終行程與軌跡,需要至少調(diào)用訂單、出票、改期、航變系統(tǒng)等,流程復(fù)雜且耗時高,并且針對一些復(fù)雜的業(yè)務(wù)場景還可能導(dǎo)致錯匹配、漏匹配等問題。

圖片

總結(jié)下來有如下幾個問題:

  • 數(shù)據(jù)私有(分散),數(shù)據(jù)模型不統(tǒng)一
  • 按照時間線進(jìn)行聚合的難度大,需要動態(tài)計算,耗時長
  • 數(shù)據(jù)存儲周期不一致,完整性不高
  • 數(shù)據(jù)分析困難,報表邏輯復(fù)雜

二、目標(biāo)

總的來說,我們需要設(shè)計一個用戶行程系統(tǒng)來滿足以下要求: 

  • 完整準(zhǔn)確的行程信息
    信息豐富完整,并保證更新及時、準(zhǔn)確
  • 使用便利
    一站式獲取,使用方效率提升,方便使用方快速接入
  • 性能可靠
    系統(tǒng)性能良好,可靠性高
  • 提升業(yè)務(wù)系統(tǒng)自動化率
    提升自動化率,上線靈活
  • 快速實(shí)現(xiàn)復(fù)雜業(yè)務(wù)流程
    對于大量動態(tài)數(shù)據(jù)的分析與過濾需要快速實(shí)現(xiàn)并上線

三、實(shí)施方案

3.1 設(shè)計思路

Q1:系統(tǒng)需要提供什么樣的能力?

1)提供準(zhǔn)確的用戶最新行程信息

用戶和相關(guān)的業(yè)務(wù)系統(tǒng)需要及時和方便的獲取到完整、準(zhǔn)確行程信息

2)輸出歷史行程變化軌跡

對于退票等場景,需要了解用戶完整的行程變化軌跡,以便于自動化處理相關(guān)數(shù)據(jù)

3)通過行程信息進(jìn)行模糊匹配

對于航變場景,航司通知某個具體航班發(fā)生了變化,系統(tǒng)需要通過這些信息匹配到對應(yīng)的訂單并進(jìn)行后續(xù)的處理

Q2:如何確保信息的豐富和準(zhǔn)確?

1)在豐富性方面,可以接入大量的數(shù)據(jù)源并提供便捷的接入方式,及時有效的采集數(shù)據(jù),提升系統(tǒng)數(shù)據(jù)的完整性

2)在準(zhǔn)確性方面,可以采用主動 + 被動等方式,多維度的對數(shù)據(jù)進(jìn)行校驗(yàn)、修復(fù),提升數(shù)據(jù)的準(zhǔn)確性

Q3:如何提升系統(tǒng)的穩(wěn)定性和可擴(kuò)展性?

1)通過分布式緩存、結(jié)構(gòu)化并發(fā)等技術(shù)提升系統(tǒng)的性能與穩(wěn)定性

2)通過數(shù)據(jù)庫的sharding、數(shù)據(jù)倉庫的賦能等方式提供在線和離線的數(shù)據(jù)處理能力,進(jìn)一步擴(kuò)充數(shù)據(jù)的應(yīng)用場景

3.2 系統(tǒng)架構(gòu)圖

最終行程系統(tǒng)主要有以下幾個方面組成:

1)最終行程數(shù)據(jù)通知與更新系統(tǒng)

即上圖中的Data Collector API,通過收集各種來源,如訂單庫、出票系統(tǒng)、改簽系統(tǒng)等的數(shù)據(jù),更新或者落地在最終行程系統(tǒng)數(shù)據(jù)庫中。同時在落地的時候也會進(jìn)行被動 + 主動相結(jié)合的數(shù)據(jù)校驗(yàn)機(jī)制,保證數(shù)據(jù)的準(zhǔn)確性。

2)最終行程查詢系統(tǒng),即上圖中的Query API,其中包含三大功能與若干個模塊

  • 最終行程查詢,對外輸出該訂單的最終行程信息,該接口流量最高,包含有緩存組件、熔斷器、限流器等,保障其性能的穩(wěn)定;
  • 行程溯源軌跡查詢,對外輸出該訂單下所有行程變化的歷史軌跡,使用方可以通過該接口拿到這個訂單的行程關(guān)系圖,感知所有變化軌跡;并且整合了價格計算模塊、錯誤數(shù)據(jù)修正模塊;
  • 行程匹配查詢,通過給定的行程要素條件,匹配能夠?qū)?yīng)上的最終行程記錄,并支持批量查詢;

3)數(shù)據(jù)存儲架構(gòu),通過分庫提升數(shù)據(jù)庫的水平擴(kuò)展能力,并且結(jié)合數(shù)據(jù)倉庫為業(yè)務(wù)賦能

3.3 信息豐富性

支持多種更新機(jī)制,方便接入多種類型的通知方,提升信息的豐富度,目前已經(jīng)接入了出、退、改、航變、票號中心等22個數(shù)據(jù)源。

策略1: 系統(tǒng)主動通知,適用于對于數(shù)據(jù)新鮮度要求較高的場景,查詢性能較好

策略2: 消息通知消費(fèi),適用于數(shù)據(jù)新鮮度要求不太高的場景,通過反查保證數(shù)據(jù)最終一致,方便系統(tǒng)解耦

策略3: 實(shí)時查詢,適用于數(shù)據(jù)變化非常頻繁,新鮮度要求高的場景;減少了數(shù)據(jù)冗余,但是在查詢和使用上存在依賴

策略4: 動態(tài)數(shù)據(jù)的過濾通知,適用于存在規(guī)則變更,但變化維度和訂單維度不同,需要掃描海量數(shù)據(jù)來獲取更新記錄的場景

3.4 便利度增加和業(yè)務(wù)提升

3.4.1 降低溯源接口接入復(fù)雜度

溯源軌跡接口對于行程關(guān)系圖的輸出形式,對于使用方的便利度影響非常大,比如如下的行程關(guān)系圖。

圖片

歷史的輸出形式為一種無限層級的樹形結(jié)構(gòu),這樣的結(jié)構(gòu)雖然能對向下的溯源查詢以及對一變多的行程變化關(guān)系提供支持,但是對于向上的溯源查詢、多變一、多變多的行程變化關(guān)系不友好,許多使用方都需要使用DFS等算法來解析數(shù)據(jù),不夠簡潔易用,容易出錯;并且樹形結(jié)構(gòu)已經(jīng)不能直觀的反映出類似二變一(中轉(zhuǎn)變直飛)的行程變化場景,而且這樣的結(jié)構(gòu)還會出現(xiàn)數(shù)據(jù)的冗余,如下圖所示:

圖片

基于以上的情況,新溯源接口選擇了類似圖的鄰接矩陣來表述行程溯源變化關(guān)系,通過TripInfo節(jié)點(diǎn)來表示頂點(diǎn)數(shù)組,平鋪出行程溯源關(guān)系圖中各個節(jié)點(diǎn)的行程信息;通過ChangeInfo節(jié)點(diǎn)來表示邊數(shù)組,主要描述行程變化關(guān)系。這樣的描述更加通用、結(jié)構(gòu)清晰并且對使用方更友好。

圖片

3.4.2 支持大量動態(tài)數(shù)據(jù)的掃描與過濾

在實(shí)際的業(yè)務(wù)場景中需要維護(hù)這樣一部分?jǐn)?shù)據(jù),它會發(fā)生變化,但引起變化的規(guī)則維度與訂單維度不一致,所以需要掃描海量數(shù)據(jù)來獲取需要被更新的記錄。同時,掃描依賴的數(shù)據(jù)可能還需要跨庫才能拿到,按照現(xiàn)有的數(shù)據(jù)庫結(jié)構(gòu)實(shí)現(xiàn)起來非常復(fù)雜。通過調(diào)研,最終采用數(shù)倉并結(jié)合業(yè)務(wù)SDK過濾的動態(tài)數(shù)據(jù)主動更新機(jī)制,實(shí)現(xiàn)了業(yè)務(wù)場景主動更新與通知的功能,該流程有如下幾個特點(diǎn):

圖片

  • 輕松整合所有依賴數(shù)據(jù)項,通過數(shù)據(jù)倉庫的大數(shù)據(jù)分析能力,可以輕松整合所有依賴的數(shù)據(jù)項
  • 對數(shù)據(jù)進(jìn)行篩選,在數(shù)據(jù)倉庫處理的流程中,添加了業(yè)務(wù)SDK的過濾機(jī)制進(jìn)行數(shù)據(jù)的初篩,將海量數(shù)據(jù)進(jìn)行過濾,并結(jié)合Double Check機(jī)制進(jìn)行進(jìn)一步的篩選,得到真正受影響的記錄
  • 觸發(fā)消息的聚合機(jī)制,同時考慮到了業(yè)務(wù)誤操作后又修改一次的情況,所以增加了消息聚合機(jī)制,聚合一段時間的消息后再真正觸發(fā)數(shù)倉進(jìn)行處理

該流程具有很強(qiáng)的通用性,通過簡單替換不同的SQL語句,切換不同的SDK,就可以輕松將該流程移植到其他業(yè)務(wù)項目中,實(shí)現(xiàn)了功能的快速上線。

3.5 性能優(yōu)化

3.5.1 提升數(shù)據(jù)庫的水平擴(kuò)展能力

最終行程系統(tǒng)在之前使用的是單庫存儲,但是隨著數(shù)據(jù)量的不斷增加,當(dāng)業(yè)務(wù)信息擴(kuò)充時,新增數(shù)據(jù)字段在數(shù)據(jù)庫層面上變的難以操作;并且如果按照業(yè)務(wù)期望的存儲時間,硬盤使用率會過高,造成了存儲瓶頸。

經(jīng)過調(diào)研,決定對最終行程數(shù)據(jù)庫做 Sharding 處理,將數(shù)據(jù)平均分配到多個分片就可以滿足存儲要求并兼顧性能指標(biāo)。

1)數(shù)據(jù)切分,基于最終行程數(shù)據(jù)特性,即訂單號訪問占比較高,同時在訂單號分布均勻的前提下,最終采用了訂單號對數(shù)據(jù)庫總分片數(shù)取模的方式,以保證數(shù)據(jù)分布的均勻性。

2)數(shù)據(jù)兼容,對于sharding庫和非sharding庫雙寫新數(shù)據(jù)的操作,并考慮數(shù)據(jù)庫存在異常的情況,需要增加異常補(bǔ)償處理機(jī)制;并且對于歷史存量數(shù)據(jù),也進(jìn)行了分批次的數(shù)據(jù)遷移以及補(bǔ)償功能,同時為了保證數(shù)據(jù)一致性,在遷移完成后也進(jìn)行了多批次的數(shù)據(jù)對比與接口對比工作,保證 Sharding 數(shù)據(jù)的準(zhǔn)確性和可靠性。

3)查詢性能,多分庫的查詢性能是分庫存在的典型問題,對于最終行程來說,采用非訂單號查詢操作,分庫后就涉及到多個分片的 All Shard 查詢,極大地增加了數(shù)據(jù)庫壓力和影響查詢性能。經(jīng)過數(shù)據(jù)統(tǒng)計,分析得到特定的業(yè)務(wù)字段查詢其實(shí)就涵蓋了非訂單號查詢的大多數(shù),從而增加其二級索引表就可以有效解決 All Shard 查詢性能的問題。

3.5.2 接入Redis緩存提升系統(tǒng)性能

總體上采用先操作數(shù)據(jù)庫,后刪除緩存;先查詢緩存,查詢不到緩存則查詢數(shù)據(jù)庫,并回填緩存的方式進(jìn)行處理。

1)提升新鮮度,在行程更新流程時、接收BinLog消息時、接收業(yè)務(wù)變更消息時都會將緩存刪除。

2)采用分級儲存查詢的模式,查詢時根據(jù)調(diào)用方所需的數(shù)據(jù)級別進(jìn)行獲取,縮小Redis獲取數(shù)據(jù)的大小,減少網(wǎng)絡(luò)開銷。

3)異步回填,啟用專用的線程對緩存數(shù)據(jù)進(jìn)行異步回填,這樣可以不拖累查詢請求本身的耗時。

4)優(yōu)化緩存容量,對Json序列化器定制規(guī)則,不輸出值為null的字段;將序列化對象中的字段通過@JsonProperty注解取一個簡短的別名,來簡化Json字符串Key的大小;使用Zstd壓縮算法對序列化后的數(shù)據(jù)進(jìn)行壓縮;通過前期調(diào)研命中率和生存時間的關(guān)系,得出達(dá)到預(yù)期命中率的最小緩存生存時間,從而進(jìn)一步減少Redis的容量。

3.5.3 結(jié)構(gòu)化并發(fā)在匹單接口中的探索

最終行程匹單接口允許使用方傳入多組條件進(jìn)行匹配,接口內(nèi)部對于這多組條件采用的是for循環(huán)的方式順序執(zhí)行的,存在并發(fā)改造的空間;且匹單接口操作數(shù)據(jù)庫存在多shard查詢的情況,對于多shard查詢,Dal底層會使用線程池并發(fā)調(diào)用,對線程的開銷較大。綜合上述問題,并結(jié)合近期發(fā)布的新的長期支持版本JDK21,發(fā)現(xiàn)了其預(yù)覽功能中的結(jié)構(gòu)化并發(fā)比較適用于匹單場景的優(yōu)化。

1)簡化多線程編程,增強(qiáng)可觀察性。

一般而言,如果我們想要實(shí)現(xiàn)并發(fā)操作,需要使用異步編程的方式來實(shí)現(xiàn),但是使用這樣的方式對于代碼閱讀性和調(diào)試來說都比較差。在目前的多線程開發(fā)中,常用的方式是使用CompletableFuture的級聯(lián)方式編寫。與單線程的代碼相比,這樣的寫法并不直觀,并且“任務(wù)終止不干凈”和“等待超過必要時間”的問題仍然存在,如果要解決這些問題還需要自己實(shí)現(xiàn)一系列模版代碼,費(fèi)力度大大增加。

而結(jié)構(gòu)化并發(fā)的一大特點(diǎn)就是讓開發(fā)人員以類似單線程的方式來編寫多線程代碼,他引出了一個結(jié)構(gòu)化任務(wù)作用域(Scope)的概念,在這個作用域中創(chuàng)建并執(zhí)行任務(wù),這些任務(wù)的生命周期都由作用域來負(fù)責(zé)管理,開發(fā)人員可以不用關(guān)系細(xì)節(jié)問題。對于作用域的任務(wù)使用try-with-resources塊,如果在執(zhí)行中出現(xiàn)錯誤,會自動調(diào)用StructuredTaskScope的shutdown方法來終止執(zhí)行,調(diào)用shutdown方法會阻止新任務(wù)的執(zhí)行,同時取消正在運(yùn)行中的任務(wù)。

圖片

2)使用虛擬線程解決阻塞問題。

StructuredTaskScope底層默認(rèn)采用了虛擬線程進(jìn)行實(shí)現(xiàn),在我們原來的認(rèn)知中,線程的使用都是昂貴的,而虛擬線程是JVM中Thread類的實(shí)現(xiàn),它是輕量級的,當(dāng)使用虛擬線程進(jìn)行代碼執(zhí)行時,如果遇到阻塞操作,便會釋放掉載體線程;并當(dāng)該阻塞操作可用時,虛擬線程又將被安排在載體線程上去繼續(xù)處理執(zhí)行。即在虛擬線程中,阻塞不是問題,因?yàn)樽枞麜r底層的載體線程已經(jīng)被釋放了

虛擬線程和結(jié)構(gòu)化并發(fā)的組合將非常強(qiáng)大,虛擬線程使阻塞不再是一個問題,而結(jié)構(gòu)化并發(fā)為我們提供了更簡單的多線程編寫方案,以更直觀的方式處理異步編程。

3.6 優(yōu)化前后數(shù)據(jù)支撐

  • 數(shù)據(jù)庫QPS降低30%
  • 數(shù)據(jù)庫CPU平均利用率下降20%
  • 平均響應(yīng)時間降低40%,P95降低30%
  • 減少機(jī)器線程數(shù)41%,CPU利用率降低25%,顯著減少機(jī)器壓力
  • 快速支持了業(yè)務(wù)功能,人力成本節(jié)約至少50%以上

四、后續(xù)規(guī)劃

1)易用性優(yōu)化

增加行程變化訂閱通知機(jī)制,進(jìn)一步提升易用性。

2)可靠性與性能提升

  • 細(xì)化熔斷和降級的策略
  • 和框架團(tuán)隊協(xié)作,積極推廣新技術(shù)在生產(chǎn)系統(tǒng)上的規(guī)范化落地
  • 探索新的數(shù)據(jù)庫結(jié)構(gòu)與數(shù)據(jù)庫選型,提升關(guān)系鏈路的存儲能力

3)可視化

實(shí)現(xiàn)整體客人行程的可視化界面,依托最終行程數(shù)據(jù)的力量,幫助業(yè)務(wù)/產(chǎn)品開發(fā)更快了解到訂單全貌,幫助提升問題解決效率。


責(zé)任編輯:張燕妮 來源: 攜程技術(shù)
相關(guān)推薦

2022-08-06 08:27:41

Trace系統(tǒng)機(jī)票前臺微服務(wù)架構(gòu)

2023-01-13 14:35:00

攜程實(shí)踐

2023-09-15 09:34:54

2022-05-13 09:27:55

Widget機(jī)票業(yè)務(wù)App

2024-05-23 17:14:49

2017-04-11 15:11:52

ABtestABT變量法

2022-06-03 09:21:47

Svelte前端攜程

2024-08-28 09:50:51

2023-03-03 09:42:27

日志數(shù)據(jù)

2020-12-04 14:32:33

AndroidJetpackKotlin

2023-05-12 10:14:38

APP開發(fā)

2020-03-05 11:15:32

IBM混合云

2017-04-11 15:34:41

機(jī)票前臺埋點(diǎn)

2017-10-09 09:12:35

攜程運(yùn)維架構(gòu)

2022-10-21 10:40:08

攜程酒店MySQL慢查詢

2017-03-15 17:38:19

互聯(lián)網(wǎng)

2022-06-10 08:35:06

項目數(shù)據(jù)庫攜程機(jī)票

2023-01-04 12:17:07

開源攜程

2022-05-27 09:25:12

攜程酒店本地緩存查詢服務(wù)

2018-05-24 17:24:35

UCloudUMStor存儲
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號