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