4小時(shí)上線一個(gè)接口,高效統(tǒng)一的攜程酒店數(shù)據(jù)服務(wù)平臺(tái)實(shí)踐
?作者 | 小豐,攜程研發(fā)總監(jiān),專注于分布式數(shù)據(jù)庫(kù)研究,大數(shù)據(jù)領(lǐng)域?qū)崟r(shí)計(jì)算和大數(shù)據(jù)應(yīng)用的系統(tǒng)架構(gòu)設(shè)計(jì)。
背景
隨著攜程酒店數(shù)據(jù)的膨脹以及個(gè)性化需求的增多,每個(gè)數(shù)據(jù)接口個(gè)性化的排期開(kāi)發(fā),因?yàn)闆](méi)有標(biāo)準(zhǔn)化,從需求討論,數(shù)據(jù)準(zhǔn)備、接口封裝、上線調(diào)試到接口api說(shuō)明,期間需要花費(fèi)大量的時(shí)間。一個(gè)接口的實(shí)現(xiàn)到生產(chǎn)上線至少需要2天甚至更多時(shí)間,這個(gè)時(shí)間成本不得不依賴排期開(kāi)發(fā);
隨著歷史接口的迭代,已對(duì)外提供的700多數(shù)據(jù)接口中,其中500多個(gè)還在使用,并且每年的增量在100多,開(kāi)發(fā)和維護(hù)成本高,特別是在追溯上游離線數(shù)據(jù)邏輯的時(shí)候,過(guò)于依賴研發(fā)資源;
不同研發(fā)團(tuán)隊(duì)技術(shù)棧不一樣,算法相關(guān)的研發(fā)更多偏向于python開(kāi)發(fā),對(duì)外輸出的接口也是由python實(shí)現(xiàn),但公司框架對(duì)java接口有更友好的支持,不同技術(shù)棧對(duì)外輸出接口的穩(wěn)定性存疑,特別是人員流動(dòng),團(tuán)隊(duì)職責(zé)變化后,同時(shí)也影響維護(hù)成本;
隨著業(yè)務(wù)的發(fā)展,各個(gè)業(yè)務(wù)系統(tǒng)的數(shù)據(jù)需求越來(lái)越多,需求響應(yīng)要求也越來(lái)越高;
通過(guò)歷史接口的分析歸類,80%以上的數(shù)據(jù)接口其實(shí)是針對(duì)離線數(shù)據(jù)或者實(shí)時(shí)數(shù)據(jù)加上需求方的檢索條件返回?cái)?shù)據(jù),沒(méi)有過(guò)多的加工邏輯或者過(guò)于復(fù)雜的業(yè)務(wù)邏輯在接口中實(shí)現(xiàn);
為了能更快速支持業(yè)務(wù)個(gè)性化需求和降低研發(fā)成本,起到降本增效的效果,同時(shí)避免煙囪式數(shù)據(jù)接口開(kāi)發(fā),提高數(shù)據(jù)復(fù)用率,避免同樣數(shù)據(jù)出現(xiàn)同樣的多個(gè)接口,也避免不同的研發(fā)團(tuán)隊(duì)拿到同一份數(shù)據(jù)都在做自己場(chǎng)景的數(shù)據(jù)接口,減少數(shù)據(jù)孤島情況。為此,我們?cè)O(shè)計(jì)了一套符合需求的數(shù)據(jù)服務(wù)平臺(tái)。
一、平臺(tái)介紹
- 統(tǒng)一數(shù)據(jù)服務(wù)平臺(tái)依托于公司soa服務(wù)基礎(chǔ)之上構(gòu)建,平臺(tái)實(shí)現(xiàn)統(tǒng)一技術(shù)方案,降低運(yùn)營(yíng)成本,提升了接口穩(wěn)定性,可維護(hù)性和持續(xù)性;
- 運(yùn)維配置,降低數(shù)據(jù)接口實(shí)現(xiàn)成本,從個(gè)性化開(kāi)發(fā)的2d+ 降低到4h甚至更快的上線,這個(gè)實(shí)現(xiàn)基本上可以不強(qiáng)依賴資源排期;
- 通過(guò)統(tǒng)一數(shù)據(jù)服務(wù)平臺(tái)可視化界面配置,不依賴java開(kāi)發(fā)人員介入,可由數(shù)倉(cāng)團(tuán)隊(duì)產(chǎn)出hive表根據(jù)需求配置接口輸出;
- 統(tǒng)一數(shù)據(jù)源,保證了數(shù)據(jù)使用的一致性;
- 為需求方申請(qǐng)接口提供標(biāo)準(zhǔn)模板,提升溝通效率以及需求方對(duì)大數(shù)據(jù)需求的滿意度。
系統(tǒng)層面架構(gòu)圖:
接口的申請(qǐng)配置流程如下圖:
二、如何實(shí)現(xiàn)
2.1 平臺(tái)收口
減少數(shù)據(jù)接口的輸出團(tuán)隊(duì)和技術(shù)方案;另外隨著業(yè)務(wù)量、數(shù)據(jù)量的增長(zhǎng),業(yè)務(wù)類型的累積,現(xiàn)在的接口不是完全靠mysql能支撐的,平臺(tái)統(tǒng)一規(guī)劃技術(shù)方案,調(diào)用方不用關(guān)心底層服務(wù)是用clickhouse,es,starrocks,redis等任何數(shù)據(jù)庫(kù)以及相關(guān)數(shù)據(jù)庫(kù)的技術(shù)特性和語(yǔ)法特征。在實(shí)際配置中,我們需要結(jié)合調(diào)用方的場(chǎng)景以及不同的olap數(shù)據(jù)庫(kù)的特性和優(yōu)缺點(diǎn)來(lái)選擇;比如:
- ES:核心,高并發(fā)非KV結(jié)構(gòu)的搜索場(chǎng)景;
- Redis:核心,高并發(fā)KV結(jié)構(gòu)場(chǎng)景;
- MySql:核心,千萬(wàn)級(jí)以內(nèi)小表簡(jiǎn)單查詢并且是高并發(fā)場(chǎng)景;
- starrocks:次核心,QPS不是非常高,單表數(shù)據(jù)量在千萬(wàn)級(jí),億級(jí)場(chǎng)景;
- ClickHouse:非核心, QPS在100以內(nèi),數(shù)據(jù)量在千萬(wàn)級(jí),億級(jí)場(chǎng)景;
- Trocks/ Hbase:非核心的KV結(jié)構(gòu)場(chǎng)景;同時(shí),對(duì)于不同的數(shù)據(jù)庫(kù),更新機(jī)制上也是需要我們注意的哪些適合于全量更新,哪些適合于增量更新;
2.2 加強(qiáng)數(shù)據(jù)利用
有些數(shù)據(jù)只要表同步過(guò),下次在其他業(yè)務(wù)場(chǎng)景使用的時(shí)候只要配置不同的查詢sql就可以對(duì)外提供使用,通過(guò)血緣關(guān)系的監(jiān)控,減少離線數(shù)據(jù)的重復(fù)同步,提升一份數(shù)據(jù)的應(yīng)用面,從而提升數(shù)據(jù)的可用性和一致性,讓數(shù)據(jù)復(fù)用而不是復(fù)制。
2.3 接口安全驗(yàn)證
每個(gè)調(diào)用方appid需要提前申請(qǐng)對(duì)某個(gè)接口的應(yīng)用權(quán)限,統(tǒng)一服務(wù)平臺(tái)通過(guò)授權(quán)token的方式,驗(yàn)證appid+token的權(quán)限防止未申請(qǐng)接口權(quán)限的應(yīng)用非法調(diào)用,其中appid是通過(guò)公司soa框架自動(dòng)獲取避免appid被串改的情況,保證接口數(shù)據(jù)的安全性和穩(wěn)定性。
2.4 限流保護(hù)
在一個(gè)高并發(fā)系統(tǒng)中對(duì)流量的把控是非常重要的,特別是在統(tǒng)一服務(wù)平臺(tái),當(dāng)某個(gè)接口因?yàn)橥獠颗老x原因?qū)е铝髁砍^(guò)設(shè)置的閥值而沒(méi)有攔住,可能導(dǎo)致整個(gè)平臺(tái)對(duì)外輸出接口都不可用。
為此,我們引入Sentinel限流機(jī)制。Sentinel是面向分布式服務(wù)架構(gòu)的輕量級(jí)流量控制組件,主要以流量為切入點(diǎn),從限流、服務(wù)降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來(lái)幫助我們保障服務(wù)的穩(wěn)定性。
實(shí)現(xiàn)原理是根據(jù)指定的時(shí)間內(nèi)生成預(yù)先配置好的令牌數(shù),每一個(gè)請(qǐng)求都會(huì)消耗一個(gè)令牌,令牌申領(lǐng)完后就會(huì)拒絕服務(wù)。目前每一個(gè)接口名都會(huì)有一個(gè)獨(dú)立的令牌,各接口間限流互相不干擾實(shí)現(xiàn)對(duì)每個(gè)接口的流量控制,qps超過(guò)設(shè)置閥值接口自動(dòng)熔斷。
2.5 數(shù)據(jù)緩存
接口的配置信息,這些信息持久化的存入硬盤中,在接口調(diào)用時(shí)會(huì)被頻繁使用,如何快速高效的獲取這些配置信息,需要使用到緩存機(jī)制。通過(guò)建立主動(dòng)和被動(dòng)緩存,避免服務(wù)器負(fù)載過(guò)高。數(shù)據(jù)源的配置信息定時(shí)緩存,接口在使用時(shí)能快速取到基礎(chǔ)數(shù)據(jù),不需要初始化。
2.6 服務(wù)契約統(tǒng)一
通過(guò)本平臺(tái)調(diào)用的接口,現(xiàn)在所有的請(qǐng)求都是由一個(gè)入口中來(lái)完成。接口收到請(qǐng)求后根據(jù)接口的配置信息自動(dòng)的進(jìn)行分流處理。請(qǐng)求契約中包含head和params兩部分,head負(fù)責(zé)接口的基本信息,用于服務(wù)驗(yàn)證和業(yè)務(wù)中轉(zhuǎn)。params參數(shù)為json字符串參數(shù)對(duì)象,服務(wù)會(huì)動(dòng)態(tài)根據(jù)json的信息與配置信息匹配進(jìn)行解析參數(shù)。response契約中包含接口成功標(biāo)志和result部分,其中result為json的字符串參數(shù)對(duì)象,需要調(diào)用方收到后進(jìn)行解析。
Request如下圖所示:
Response 如下圖所示:
2.7 數(shù)據(jù)服務(wù)配置和映射
一個(gè)服務(wù)接口由數(shù)據(jù)源、sql語(yǔ)句、請(qǐng)求參數(shù)及響應(yīng)參數(shù)組成。其中sql語(yǔ)句中的參數(shù)使用 ?、{序號(hào)} 占位符替代,與請(qǐng)求參數(shù)一起使用,sql有多少個(gè)參數(shù)占位符,請(qǐng)求參數(shù)就需要配置多少,接口運(yùn)行時(shí)會(huì)根據(jù)請(qǐng)求的參數(shù)自動(dòng)匹配到sql參數(shù)中。響應(yīng)參數(shù)為了在查詢結(jié)果中映射字段,sql查詢輸出的結(jié)果 ,可以通過(guò)映射轉(zhuǎn)換真正想要的輸出參數(shù),配置的響應(yīng)參數(shù)就是接口服務(wù)返回的查詢結(jié)果。如下圖是配置sql的查詢方式:
2.8 契約文檔自動(dòng)生成
個(gè)性化接口開(kāi)發(fā),需要對(duì)接口進(jìn)行解釋,告知調(diào)用方如何調(diào)用。結(jié)合接口輸入和輸出參數(shù)都是自定義的特點(diǎn),定義一套服務(wù)文檔展示模板,文檔中包含所有的調(diào)用該接口的詳細(xì)信息。只要定義好接口后,會(huì)動(dòng)態(tài)的生成契約文檔,申請(qǐng)使用該服務(wù)的團(tuán)隊(duì)會(huì)通過(guò)郵件方式發(fā)送信息,節(jié)省接口解釋成本。文檔在線效果如下圖,同時(shí)也會(huì)以郵件形式推送給申請(qǐng)人。
2.9 服務(wù)監(jiān)控
服務(wù)接口正常運(yùn)行后,借助于公司的clog和ck日志框架來(lái)監(jiān)控接口調(diào)用情況。Clog監(jiān)控主是要記錄請(qǐng)求接口從開(kāi)始調(diào)用到返回所有的過(guò)程記錄,包含每個(gè)過(guò)程節(jié)點(diǎn)的調(diào)用時(shí)長(zhǎng),請(qǐng)求參數(shù)及返回參數(shù)。方便定位接口request的整條鏈路。ck監(jiān)控主是要記錄接口層請(qǐng)求的參數(shù),返回的參數(shù)和響應(yīng)時(shí)間。每次請(qǐng)求只記錄一次,可以統(tǒng)計(jì),監(jiān)控每個(gè)時(shí)段調(diào)用的次數(shù),接口響應(yīng)的時(shí)長(zhǎng)等信息。
2.10 生產(chǎn)運(yùn)行效果
2021年12月初上線至今,目前對(duì)接調(diào)用方appid 10個(gè),提供100多個(gè)接口服務(wù)。請(qǐng)求量隨著接口的增加趨勢(shì)增長(zhǎng),目前每天的請(qǐng)求量達(dá)390多萬(wàn)次。每個(gè)接口上線周期為半天時(shí)間或更短。接口上線只需要根據(jù)需求方配置后立刻就可以在線使用,大大的減少了上線的周期。生產(chǎn)接口響應(yīng)時(shí)間91.49%在10ms內(nèi),99.99%是在100ms以內(nèi)。
三、后期展望
現(xiàn)在所有的接口都部署在一個(gè)集群,對(duì)于一些調(diào)用方,我們其實(shí)也可以區(qū)分高中低三個(gè)等級(jí),將高優(yōu)調(diào)用方部署在一個(gè)獨(dú)立集群上,中等調(diào)用方部署在一個(gè)集群上,低優(yōu)調(diào)用方部署在獨(dú)立集群上,相互之間資源隔離。
實(shí)現(xiàn)測(cè)試環(huán)境的打通。由于大數(shù)據(jù)環(huán)境大部分只有生產(chǎn)環(huán)境,沒(méi)有測(cè)試環(huán)境和測(cè)試數(shù)據(jù),所以統(tǒng)一服務(wù)平臺(tái)現(xiàn)在只能用于生產(chǎn)環(huán)境。開(kāi)發(fā)環(huán)境或者測(cè)試環(huán)境無(wú)法調(diào)用聯(lián)調(diào),對(duì)于調(diào)用方只能通過(guò)mock的方式測(cè)試,這個(gè)也是后面我們需要考慮如何利用最低的成本實(shí)現(xiàn)測(cè)試環(huán)境的可用性,讓調(diào)用方使用起來(lái)更加便捷。