5億用戶萬億存量,揭祕餘額寶背後的服務治理架構!

ArchSummit 全球架構師峯會北京站上,餘額寶首席架構師李鑫做了《餘額寶背後的服務治理架構》的演講。本文根據演講整理而來。

餘額寶自 2013 年上線後,經過幾年的飛速發展,目前存量已突破萬億,用戶規模達到 5 億以上。作爲一支現象級的金融產品,餘額寶如何針對不斷飆升的海量業務做 IT 整體架構的治理、優化和創新?本文將首次揭示天弘基金技術團隊在服務治理、數據治理、團隊協同治理這三大領域的治理探索及經驗和教訓。

餘額寶業務及架構變遷

餘額寶算是中國第一支真正意義上的普惠金融產品,它本質上是一支貨幣基金,背後是天弘的增利寶基金。由於與支付寶的關係,它既是理財產品,又是支付產品,理財和支付的雙重屬性,再加上互聯網產品所特有的極簡的用戶體驗,讓餘額寶一經推出,迅速成爲 “爆款”,短短六年獲得了驚人的發展。毫不誇張的說,餘額寶的出現,開啓了中國的全民理財時代!

餘額寶架構變遷歷史

爲了適應業務的爆炸式增長,餘額寶的技術架構前後共做了 4 次大的變更,每次技術變更的背後,都承載了天弘技術團隊對系統規模、可擴展性及升級成本的綜合考量和平衡之道。

餘額寶上線之初,解決的是“從無到有”的問題。

當時沒有其它類似的互聯網金融產品可以做參考,我們採用了傳統的典型企業級金融架構。採用自建 IDC 機房的方式,用硬件負載均衡設備將交易請求接入進來,前端是由六臺 weblogic 構成的小型前置處理集羣;請求被稍做處理後,即被推送到後端由金正的基金交易中間件構建的集羣做業務處理,其中 KCXP 和 KCBP 分別是金正公司的基金交易消息中間件和業務中間件;業務數據存儲採用的是兩臺 Oracle 數據庫服務器構建的一主一備小集羣,這個是線上庫,爲了緩解數據存儲壓力,歷史交易記錄會被定期抽取到一個同樣架構的歷史庫服務集羣。硬件方面採用的都是惠普小型機設備,數據備份則採用 EMC 的產品。

這是典型的 IOE 架構,全套的商用軟硬件配置,成本很高。架構體系裏的每一層雖然都採用了集羣的方式,但更多的是使用主備模式,而不是負載均衡的分佈式模式,因此係統的單點資源負載壓力較大,尤其是數據庫,基本上就是單庫模式(另一個庫是備庫),擴展性較差。

當時的系統容量設計上限是能支持千萬級用戶。傳統基金銷售模式是走代銷機構,投資基金用戶也多以理財爲目的,所以每天可能處理的帳戶開戶也就是幾萬到幾十萬的規模。由於餘額寶對接的是支付寶,支付寶的用戶規模達到千萬級,這是設計產品時對需求的定位。當時預估,這個設計容量怎麼都能扛個幾年。結果,上線短短 10 天左右,新開戶數已經突破 100W 了,按這個速度,3 個月左右數據庫容量上限就要被突破!事實也是如此,我們三個月就達到一千萬的客戶,餘額寶一期系統的生命週期只有三個月!

所以一期系統甫一上線,團隊就不得不開始考慮擴容,計劃將容量擴充 30~50 倍,計算規模也同步增加。如果還是採用一期系統的純商用軟硬件的模式進行橫向擴展的話,成本要達到 1~2 個億,這樣的成本對於當時天弘這樣一家小型基金公司而言,是不可負擔之重!因此,在阿里的建議下,我們決定整體上雲

做出這個決定的壓力是非常大的,因爲當時沒有任何一家金融公司和基金公司會將他們的核心交易系統構建在雲上。但在巨大的成本壓力之下,我們走出了這一步,成爲那個第一個吃螃蟹的人!經過緊張的遷移工作,我們將系統整體搬遷到阿里雲上,這就有了餘額寶 2.0 架構。

2.0 的架構中用阿里雲上的軟件負載均衡 SLB 替換了硬件負載均衡;用阿里雲上的虛擬計算單元 ECS 替換小型機成爲前置服務及中間件服務的服務器;用阿里雲的 web 服務替換了前置服務器上的 weblogic。同時將服務集羣的數量從十幾個節點擴充到近 60 個節點。

最大的變化是數據庫,原來的 Oracle 單庫被替換成了阿里雲上的一個 50 個節點的 RDS 集羣,實際上就是進行了分庫分表的拆分。經過測算,需要使用 50 組業務節點,但在拆分時,考慮到擴展性,並未簡單地拆分成 50 份,而是根據用戶帳號 ID 作爲分片主鍵將所有的核心業務表,包括資產、賬戶、交易等都各拆分成 1000 份,然後每個節點處理 20 份數據(物理子表)。這樣做的好處是將來如果系統遇到瓶頸,需要擴容時,不需要對拆分算法進行修改,而且數據平均遷移時只需要以庫爲級別進行,從而避免了拆表。

上雲後,不僅數據庫總容量有了幾十倍的提升,交易處理效率也從一期的 120W 筆 / 小時提升到了近 2000W 筆 / 小時;最大清算時間從之前的 7 個多小時降低到不到 2 個小時;而總成本,才增加了不到 1 倍。所以,上雲對我們系統整體效率的提升和成本的降低有非常明顯的作用。

餘額寶 2.0 的架構奠定了餘額寶後續架構的基調,它在線上穩定運行了近 3 年,中間經歷了幾次小的升級優化,有力的支撐了這個過程中的各種業務創新,但也在支撐業務快速發展中埋下了一些“坑”。

2016 年,我們決定對系統進行一次大升級。這次升級的主要基調就是“業務邏輯重構,優化清算流程”,這就是餘額寶 3.0。

這一階段的業務邏輯複雜度要遠遠高於 3 年前,因此 3.0 的架構中,我們首先對服務按直銷和代銷業務進行了拆分,並在拆分後,將服務節點從原來的 60 臺擴充到了 340 臺。由於數據庫前期預留的 buffer 比較大,並沒有成爲本階段的瓶頸,依然維持了 50 個節點的規模。

這次升級之後,總體計算能力有了較大幅度的提高。處理效率比起 2.0 階段增長了 2 倍多,也支撐了 2016 年春節期間日交易 4 億多筆的峯值。但是,清算時間比 2.0 時期有較大增長,這成了系統的一個“隱患”。

2017 年,爲了配合支付寶拓寬線下支付場景,並將業務推廣覆蓋到三、四線城市,同時,也要解決清算時間過長的隱患,我們規劃了餘額寶 4.0 的升級。

這一階段的系統規模已經很大了,如果還是按 3.0 的架構進行橫向擴充的話,成本將呈線性增長。經過綜合考量,決定在升級前,先優化單節點的處理性能,提高效率及負載後再擴容,以降低總體的升級成本。

因此,這次升級首先將直銷和代銷業務合二爲一,同一臺計算單元既處理直銷業務,也處理代銷業務,提高了單點的處理效率。在此基礎上,再進行擴容,將計算單元從 340 節點擴充到 480 節點,數據庫擴容 4 倍。通過這兩步優化及擴充動作,最終系統的容量及計算能力均有了 4~8 倍的提高,這套新的架構支撐我們平穩度過了 2018 年雙十一及春節的交易高峯。

看到這裏,大家可能會有疑問:一般在系統服務化改造中,服務是會被拆的越來越細,爲什麼我們反其道而行,反而對服務進行了整合?這是因爲,餘額寶發展到這個階段,業務模式已經比較成熟,通過細粒度的服務模態來保證可擴展性的需求已經不是那麼強烈;另一方面,系統規模龐大,擴容的成本成爲重點考慮因素;綜合這兩方面的考量,適當增加單點的複雜度,可以降低整體成本。

餘額寶當前技術生態

目前,針對餘額寶這單隻基金已經建立起了一套完整的技術生態體系,它的核心是餘額寶的產品、帳號、交易、清算等模塊,在結合實時調用和文件交互兩套接口的基礎上,構建了電商大數據的分析體系及一系列輔助支撐系統。同時,餘額寶系統和其它第三方系統也有大量的交互,包括支付寶、監管、直代銷渠道等等。

倒逼出來的大規模服務化及業務中臺建設

餘額寶系統的建設直接鍛鍊了天弘的技術團隊,讓我們明白了大型互聯網應用是什麼樣的玩法,這也直接推動了天弘基金銷售平臺的整體服務化改造。接下來,我將詳細介紹基金實時交易平臺的服務化改造。

基金業務簡介

在開始這部分內容之前,先簡單的介紹一下基金公司的業務。

基金公司最核心的業務就兩塊,一個是基金的交易,另一個是投資。我們從直銷和代銷渠道把交易請求“接”進來,在我們的核心交易系統進行申購、認購、定投、贖回、轉換等等操作,這個過程裏,會涉及與支付渠道、銀行等一系列的交付。同時,還有大量的清結算和 TA 清算,這個過程裏,要與銀證監會、中登等一系列監管機構有數據上的交互。聚攏過來的鉅額資金會被統一管控,並投入到股市、債市、貨幣市場等投資市場去賺取收益。圍繞這個業務還有相應的投研、基金產品管理、風控、客服等中後臺的業務支持。

以上,就是基金公司的日常業務模式。

基金實時交易系統服務化改造

在天弘早期的基金銷售系統建設中,其實沒有什麼服務化的概念,當時常用的做法是有什麼類型的業務,就針對這種業務單獨開發一套獨立的銷售及清結算系統,存儲也是各用各的。由於業務量普遍不大,這些系統往往採用單體架構模式,不考慮橫向擴展性。經過多年的發展和積累,內部多套直銷及代銷交易系統並存,系統間帳號沒有打通,用戶的資產數據無法統一,用戶體驗差;另一方面,各系統間功能重複的現象嚴重,不僅重複佔用軟硬件資源,版本的控制也很麻煩。

這種狀況甚至在我們整體遷移到雲上之後還存在了很長一段時間。因此,所謂的“服務化”,並不僅僅是上雲那麼簡單,它還涉及到架構思維的轉變。

痛定思痛之後,我們決定對系統進行服務化改造。將這些系統中通用的能力,包括用戶賬戶、交易、支付、資產、結算、權益、投顧等功能抽取出來,改造成服務後,以服務集羣的形式獨立部署,統一對上層應用提供通用服務,這就是我們內部俗稱的 8 大服務中心,它們共同構成了後臺的通用服務層。原來的業務系統拆分之後變得更輕了,更多的充當了一個交易大廳的角色,我們稱之爲前臺服務層。我們的網關層共提供了兩套網關,一套是 SLB,另外一套是移動網關,用戶的交易請求通過網關層被統一接入進來,先在前臺服務層進行協議解析、安全校驗及簡單的業務邏輯處理後,再通過調用後臺通用服務層的服務進行基金的相關交易。

由於我們早期前端的業務渠道不多,直銷只有 APP 及官網銷售兩個渠道,代銷只有餘額寶和基金淘寶店,業務比較單一,這樣的兩層服務化拆分已經夠用了,前臺服務層的粒度已經足以支撐正常的業務迭代速度。

但是業務很快進入一個快速發展的階段,這個時期有大量的終端渠道要接入,除了早期的銷售渠道之外,還增加了微信、釘釘及其它多家第三方的銷售及運營渠道,業務迭代的速度也明顯加快。舉個例子,我們有一個叫“目標贏”的定投產品,在很多終端渠道上進行銷售,每個渠道對這個產品的銷售或多或少都有一些個性化訴求,有的在客戶校驗上要增加特殊要求,有的要求在產品銷售上疊加一些額外的運營規則。綜合來看,這些終端渠道對“目標贏”這個產品的功能訴求中,有 80% 是一致的,只有 20% 的個性化要求,如果還是按早期的兩層服務劃分方式,我們需要爲每個渠道都開發一個重複度很高的前臺服務,這明顯不划算,太重了。

怎麼辦呢?繼續拆!將“目標贏”這個能力中,和渠道無關的 80% 通用業務功能拆出來,繼續下沉,形成一個新的服務分層,我們稱其爲業務服務層;這樣還不夠,我們繼續將前臺服務層中剩下的 20% 個性化能力中和業務無關的功能,包括協議適配、拆包、安全校驗這些功能也拆出來,和網關層合併,形成了安全網關這個新的擴展。這樣,前臺服務層只剩下 10% 左右的業務功能了,而且裏面大部分的邏輯是對業務服務層及通用服務層的能力進行組裝和聚合,這個時候,前臺服務層已經被拆的很輕了,我們改稱其爲聚合服務層。通過這種繼續拆分的方式,我們將早期兩層的服務化分層架構,演進成包含聚合服務層、業務服務層、通用服務層的三層服務化分層架構。

17 年之後,“業務中臺”這個概念大火,我們重新審視我們的服務化架構,發現業務服務層這個新的服務分層和業務中臺定義高度匹配,把它定位爲基金銷售業務的業務中臺毫無“違和感”。因此,聚合服務層、業務服務層、通用服務層這樣的三層分層的定義換個說法就是業務前臺、業務中臺、通用後臺。這樣的分層架構也並非我們刻意爲之,而是基於業務的驅動,在服務化的架構下自然形成的。

目前,這整套服務化平臺都是在阿里雲及螞蟻金融雲的 IaaS 層及 PaaS 層能力基礎上構建的,我們在它們的基礎之上還構建了相應的日誌監控、服務治理、APM 動態調用鏈跟蹤、運維管控等一系列能力。

以上,就是我們目前基金實時交易平臺的整體服務化的架構。

業務中臺

將我們線上系統架構變遷的整個歷史拉通來看,可以看到經歷了 3 個階段。

早期,就是典型的單體 + 豎井架構,複用性及可擴展性都差。

在服務化的初期,將系統進行了兩層服務化拆分:前臺業務服務層 + 後臺通用服務層。在業務發展比較平穩、前端業務渠道不多的時候,兩層服務化分層已經足以支撐業務的正常迭代。

隨着業務的快速發展及多端適配需求增多,兩層架構下的前臺業務服務層還是太重,無法支撐業務的快速變更,這時候將其繼續拆分,將業務域的通用服務繼續下層出新的業務中臺層,這就形成了現在的三層服務化分層架構。

在目前的三層服務分層架構下,通用服務被不斷下沉,所以越底層的服務被抽象度越高,也更通用、更靜態,不會經常改變;越靠近前端的服務越貼近業務,越不穩定,會隨着業務的快速變化而不斷改變,客觀上也必須保持更輕的體態。

基於我們系統服務化的經驗,談談我個人對業務中臺這個概念的理解。

所謂“業務中臺”,本質上屬於服務分層的概念,因爲既然有中臺,架構設計上就一定存在多層,一定存在前臺和後臺,脫離前臺和後臺談中臺沒有任何意義。中臺這個概念大概在 2017 年的時候由阿里正式提出來,之前基本上沒有人提這個概念,大家更多是在談服務化和服務分層,實際上它不是一個新的東西,而是對“現有概念”的重新包裝,新瓶裝舊酒而已。這個概念的本質就是“服務化 + 服務分層”,它只是服務化分層中的一層而已。

爲什麼會形成業務中臺這樣一個服務層呢?本質上還是和業務的發展息息相關,業務的快速發展會驅使你不斷的對服務進行拆分,並將通用服務不斷下沉,只有這樣,才能將服務拆的更小,而服務粒度越小,可組裝性越好。只有這樣,我們纔可以根據不同的業務形態,通過服務組裝和聚合的方式快速構建出前端應用,從而實現更快的開發速度,以支持業務的快速迭代及試錯。

如果你的業務形態比較單一,發展相對靜態的話,就不會有那麼強烈的服務分層和拆分的需求,自然就長不出所謂的“業務中臺”的服務分層。所以,業務中臺的建設要順其自然,強扭的瓜不甜,企業需要根據自己的業務特徵來判斷是否需要建設業務中臺。

業務中臺的存在解決了前臺業務服務和後臺通用服務之間的適配問題,讓前臺服務不需要通過大量的代碼來處理業務邏輯,只需要通過少量的粘合劑代碼來對中臺專屬業務領域的通用服務和後臺跨業務領域的通用服務進行快速組裝及聚合,這就從根本上降低了前臺服務開發的工作量和成本。業務變化越快,多端適配的需求越多,中臺建設的收益越大;如果業務比較平穩,也沒那麼多的業務渠道,那麼中臺建設的意義就不大了,像我們早期所採用的前後兩層的服務化架構就能工作得很好。

既然業務中臺本質上是一個服務分層,那麼服務化架構的分層質量對業務中臺的形成就有很重要的意義。如何進行更好、邊界更清晰的服務分層,會直接影響到能否成功長出業務中臺這個分層形態。

討論這個問題之前,先舉一個我自己的例子。我目前雖然是負責技術團隊的管理,但每隔一段時間,都會給自己分派一些迭代的開發工作,以免離一線開發太遠(^_^)。前段時間,我負責了一個叫理財月報的功能模塊的開發,同時在這個項目裏,還挑戰了一把“全棧”:前端 H5 和後端的 Java 服務開發都由我一個人負責。在我們團隊規範中,嚴格規定了前端應用必須儘量少的承載業務邏輯。剛開始我還嚴格執行這一規定,但在迭代中間,產品提了一些功能變更,分析後,發現服務端修改比較麻煩,我當時“懶”了一下,直接就在前端通過 JavaScript 把邏輯給寫了。迭代結束後,重新審視這個功能模塊,雖然能力實現了,但架構規範並沒有貫徹的很好,前端還是多少承載了一些本不必要的邏輯處理能力。

我舉這個例子的目的就是要說明,如果由一個團隊(或者一個人),同時負責多個架構分層的能力開發的話,很容易由於惰性或者自我妥協的情緒而導致分層邊界混淆不清,最終長出來的,很可能就是一大坨互相耦合在一起的服務,更別談清晰的層次劃分了。所以,我們的後臺通用服務、中臺業務服務和前臺服務都分別由不同團隊負責,大家負責的能力之間存在清晰的劃分邊界,共同遵循嚴格的服務接口契約。這也符合康威定律:組織的協同及管理模式必須與所採用的系統架構相匹配。

總結來說,要最終推動業務中臺這樣的服務分層的誕生,業務驅動、服務分層、通用服務下沉、組織拆分都是必不可少的因素。

以上就是我們在服務化以及業務中臺建設方面的一些實踐經驗。接下來,我來講講服務化對我們整個研發體系所造成的衝擊、帶來了哪些困難,以及我們是如何應對的。

服務化帶來的衝擊及服務治理

我們走上服務化這條道路的訴求非常簡單直接,就是要解決單體及豎井架構所帶來的系統可擴展性及可維護性的問題。我們曾經以爲,只要引入服務化,這些問題都能迎刃而解,從此就能走上研發的康莊大道 ^_^。

但當真正踏上這條道路時,才發現,走上的壓根兒就不是一條快車道,而是一條爛泥地,遍地都是坑。我們確實解決了一些問題,但同時也遇到了一系列新的問題。

服務化的衝擊及挑戰

服務化的本質就是一個“拆”字,原來的單體應用被拆成了大大小小的應用集羣和服務集羣,並被分散到網絡的各個節點,由不同的團隊負責,每個團隊各管一段。

在這個離散化的大背景下,運維和研發都會遭遇一系列新的問題和挑戰,包括集羣環境中故障的定界定位:你如何快速定位問題出在哪?整個集羣的調用關係是什麼樣的,如何梳理?合理不合理?整個集羣的性能瓶頸在哪?這些都是運維要直面的問題。對研發來說,挑戰也不少。團隊被拆分了,團隊之間如何高效的協作?系統被拆分了,功能被分散到遠程節點,如何做調試?分佈式架構下的數據一致性如何保障?等等…

所以,架構的變更帶來的影響是全方位的,影響的絕不僅僅只是應用系統,它會對整個研發體系,包括開發、運維、團隊組織、協同都帶來衝擊,你必須構建起一整套從線下到線上的新的能力體系來支撐這套新的架構。很多團隊沒能構建起這套能力體系,直接在服務化的“反噬”下,倒在了路上,看不到服務化帶來的“曙光”。

下面來看看,我們是如何破解這些困局的。

分佈式事務

事務的一致性和可用性問題是分佈式環境下“老生常談”的問題了,相信大家也或多或少遇到過。它不僅僅是服務化的問題,而是分佈式架構的一個共性問題,所以我在這裏把它單獨“拎”出來講講。

針對分佈式事務,我們採取了 3 級應對策略。

首先,在分庫分表操作中,堅持“實體組”優先的策略,儘量按照統一的“片鍵”進行分庫分表操作。比如,如果統一按“用戶賬戶 ID”作爲分庫分表鍵的話,那麼用戶相關的交易、資產、支付等信息都會落到同一個物理庫實例中。這樣,針對此用戶的相關操作,本地事務就可以生效,避免了分佈式事務的使用,因爲對於任何分佈式事務而言,不管做不做資源鎖定,爲了有效保障事務狀態,都需要額外的資源處理消耗。

其次,我們還提供了自研的支持多級事務的 TCC 服務,以應對不可避免的分佈式事務需求。採用 TCC 的最重要原因是與其它資源管理器相比,它相對簡單,我們不用關注資源層面,只需要關注服務接口即可。上面的第二張圖是 TCC 的典型架構模式圖,相信只要研究過 TCC 的同學們一定看過這張圖,第三張則是我們自研 TCC 的詳細的交互架構圖,能體現更多技術細節,可供大家參考。

從我個人的理解而言,實現一個 TCC 框架(獨立服務)並不麻煩,最核心的是要解決兩大問題。一是參與事務的業務數據的緩存和回放問題,我們在做 TRY 操作時,需要將事務數據緩存起來,可以存到數據庫或者分佈式緩存中,但不能緩存在本地,這樣不可靠。當框架做 Confirm 和 Cancel 操作時,再用緩存的事務數據去運行特定的服務邏輯。這就要求在 TRY、Confirm 和 Cancel 的方法構造上要有一定的約束,相互之間要能夠識別哪些入參是事務數據。另一個是父子事務的事務 ID 的傳遞問題,我們通過分佈式服務框架的“非業務傳參”來解決這個問題,一旦某個事務構建了一個事務 ID,這個事務 ID 就會被放置到環境上下文中,並隨着 RPC 調用傳遞到遠程服務,遠程服務如果偵測到上下文中已經存在事務 ID 了,就不再構建新的事務 ID,這樣的話,父子事務之間就通過同一個事務 ID 關聯在一起。

最後,最終一致性的保障一定是“對賬、對賬、對賬”!這是最傳統,也是最可靠的最終防線,這也是金融公司的基礎能力,這裏我就不展開詳細說了。

三位一體的服務治理架構

企業的服務化之路要走得順暢,一定要兩條腿走路,一條腿是需要一套很好的分佈式服務框架;另外一條腿,就是要做服務治理。只有這兩條腿都健壯,服務化之路才能順利。

我們在服務化之後就同步開展了服務治理的工作,對服務治理這個概念的理解也隨着實踐經歷了由淺入深的過程。

這裏直接給出我們做服務治理的整體架構圖。服務治理既要進行線上的治理,也要進行線下的治理,通過線上線下兩大維度進行治理指標的採集,並把它彙總到數據倉庫中,進行統一的度量和分析。

這些度量指標中,有相當一部分線上的性能及異常指標會被轉化爲運維事件,一旦觸發我們預先設置的閾值,就會被進一步轉化成治理“管控指令”,並通過調度中心下發,驅動雲上的資源編排和調度能力,進行服務的彈性伸縮、擴容縮容操作,以應對流量的波動,或者直接驅動服務進行服務內部的限流、降級、容錯、路由調整等管控操作。

另外一部分度量指標,尤其是線下度量指標,包括架構、開發、測試、運維、過程協作效率等指標會通過治理委員會(泛指,治理成員的集合)進行人爲的深入分析,並制定出治理決策,這些治理決策會通過相關的管理措施進行落地。

這樣,我們就通過服務的度量、管控、管理三大舉措,構建起一個三位一體、圍繞服務治理的閉環體系。在這套體系中,針對服務的度量是進行服務管控和管理的前提和基礎,只有看得到,才能管得到,必須先解決“看”的問題,才能解決“管”的問題。接下來,我們就來重點介紹如何構建微服務的度量及分析體系。

服務度量體系

管理學大師彼得·德魯克說過“如果你不能度量它,你就無法改進它”,強調的就是度量的重要性。

度量的第一步,就是度量指標的採集。

前面介紹了,微服務的治理囊括了線上及線下體系,同樣的,服務治理度量指標的採集也要線上線下同步進行。

在線上,可以通過服務註冊中心獲取到服務的註冊信息及服務的管控指令信息,通過各個微服務主機節點上的主機日誌、應用及服務日誌、APM 監控的調用鏈日誌,可以獲取到相關的性能及異常指標信息。

線下的指標就更多了,通過需求管理系統,可以採集到 UserStory 及各類需求的基本信息;通過項目管理系統可以採集到開發人員、開發團隊、開發任務的基礎信息;通過測試相關的管理系統可以採集到測試用例及測試 bug 的相關定義信息及過程指標信息;通過源碼倉庫及軟件版本倉庫可以採集服務之間的調用關係(代碼掃描獲取到的靜態調用關係),以及最終研發產出物的基本信息。

軟件研發是一個強調協同的羣體行爲,產品、開發、測試、運維需要緊密合作。爲了達到更高效的配合,我們經常會採用一些協作模式,比如針對開發和測試之間的配合,採用持續集成(CI);針對產品、開發、測試的協作,採用敏捷協作模式;另外,還會使用一些 DevOps 的 Pipeline。不管採用何種協作模式,都可以從其相關的過程管理系統中抽取出相關的過程指標事件,比如一個任務什麼時候完成設計、什麼時候開始進入開發、什麼時候完成開發…等等,這也是一大類很重要的治理度量指標。

有了以上這些線上線下指標,就可以將它們統一彙總到數據倉庫,進行進一步的深度度量和分析。

來看看最終針對微服務治理的度量及分析體系是什麼樣子。從下往上看,首先通過各個指標來源渠道獲取到上述的各類度量指標,並把它們以 ODS(操作型數據)的格式彙總到數據倉庫;通過數據模型抽取出主數據(MDM),這些主數據包括了服務、需求、任務、人員、團隊等,在此基礎上,通過不同的數據主題(Topic)構建起一個多層的“數據集市”,這些數據主題包括了異常、性能、資源、調用關係、容量、系統、測試、開發、運維協同效率等;在這個數據集市的基礎上進行各類數據分析,包括性能分析、容量分析、健康度分析、團隊及個人的質量報告、質量趨勢、動態調用鏈及靜態調用鏈的深度梳理、以及各維度的彙總報表。根據這些分析報告,由治理委員會進行深度的分析並制定出各類的治理決策,或者通過人爲或自動化的機制發出各類管控指令。

治理決策和管控指令就是微服務度量及分析體系的最終產出物

有了治理決策和管控指令,就可以對微服務的線上及線下體系進行治理,首先來看一下對線上服務體系如何進行治理。

服務線上治理之服務限流

服務限流是微服務集羣自我保護的一種常用機制,我們對線上調用比較頻繁及資源佔用較大的服務都加上了相應的限流舉措,並構建了單機限流集羣限流兩套限流措施。

首先來看一下單機限流,它有多種限流算法可供選擇,最主要的是兩種,漏桶算法令牌桶算法。它們之間有什麼區別呢?打個比方,比如今天這個會場的人已經爆滿了,門口保安開始限制客流,一種舉措是會場中出來一位聽衆,才放進去一位聽衆,這樣可以保證會場中的聽衆總數是固定的,人人都有座位,這就是漏桶算法 — 必須有“漏”出去的,纔能有進來的;另外一種舉措是不管有沒有聽衆出去,保安固定每隔 5 分鐘就放一波客人進來,這和春運火車站的波段式限流非常類似,可以保證客流比較均勻,但是這種策略也有一定的風險,如果聽衆離開得不夠及時,會場中的人總數可能會升高,導致一部分聽衆沒有座位,這就是令牌桶算法。因此,如果要對線上併發總數進行嚴格限定,漏桶算法可能會更合適一些,這是單機限流機制。

單機限流下,各個服務節點負責各自機器的限流,不關注其它節點,更不關注集羣總調用量。但有時候,因爲後臺總資源是有限的,雖然各個單節點的流量都沒有超,但總流量可能會超過後臺資源的總承受量,所以必須控制服務在所有節點上的總的流量,這就是集羣限流。

集羣限流能力的構建要更復雜一些。首先在各個微服務節點上要有一個計數器,對單位時間片內的調用進行計數,計數值會被定期的彙總到日誌中心,由統計分析器進行統一彙總,算出這個時間片的總調用量。集羣限流分析器拿到這個總調用量,與預先定義的限流閾值進行比對,計算出一個限流比例,這個限流比例會通過服務註冊中心下發到各個服務節點上,服務節點基於限流比例各自算出當前節點對應的最終限流閾值,最後利用單機限流進行流控。

可以看到,這是一套環環相扣的、各環節緊密協作配合的技術體系。單純拎出一個點來看,實現技術都不麻煩,但要構建起貫穿整個技術棧的技術體系,則需要有一套統一的技術標準,各個環節都遵循這套標準,並對不符合標準的應用及環節進行改造,保證標準落地,這樣才能構建起完善的限流技術體系。因此,構建服務限流能力的難點,一是標準化,二是體系化

體系化的構建是最難的,但也是最有威力的,大公司往往就是依靠體系的力量去構建起護城河,從而去碾壓沒有體系能力的小公司。

另外,限流一大原則是限流動作儘量前置,畢竟被限制的流量註定要被“拋棄”,越早處理越好,免得無謂的消耗資源。

服務線上治理之集羣容錯

集羣容錯是微服務集羣高可用的保障,它有很多策略可供選擇,包括:

  • 快速失敗(failfast)
  • 失敗轉移(Failover)
  • 失敗重試(Failback)
  • 聚合調用(Forking)
  • 廣播調用(Broadcast)

很多容錯策略都是靠重試來實現的,但不管你決定使用哪種集羣容錯策略,一定要注意控制重試的次數,尤其是線上負載已經很高的時候,如果重試次數太多,一方面會推高服務被調用方的負載及併發,另外一方面會導致服務調用方的調用延時增長,雙重因素疊加之下,最終極可能導致“服務雪崩”、集羣被“擊穿”。

所以,在使用集羣容錯的時候,一定要設置最大重試次數。另外,有可能的話,儘量做“重試減速”,也就是讓每次重試的間隔時間越來越長(可以考慮採用指數),這樣可以將重試帶來的壓力盡量分散到一個足夠長的時間段,避免阻塞在一起造成人爲的 DDOS 攻擊。

服務線上治理之服務降級

服務降級和服務限流類似,也是微服務集羣自我保護的機制。一般在線上動用服務降級手段時,都是線上比較危急的時候,生死存亡了,這時候留給你思考和反應的時間不多,所以在使用服務降級之前一定要做好預案,提前梳理出核心業務鏈路和非核心業務鏈路,然後通過降級開關一鍵把部分或所有非核心鏈路降級,這樣才能“救命”。

服務降級也有很多手段可以使用,包括:

  • 容錯降級
  • 靜態返回值降級
  • Mock 降級
  • 備用服務降級

我們常說的熔斷,本質上也是容錯降級策略的一種。相比一般容錯降級,熔斷提供了更爲豐富的容錯託底策略,支持半開降級及全開降級模式。

構建服務降級能力也和限流機制類似,同樣需要堅持標準化和體系化。

服務線上治理之容量規劃

線上的流量今天漲一點,明天漲一點,如果麻痹大意,或者監控手段不到位,說不定哪天服務就被沖垮了,所以要對線上的流量時時進行規劃,以做到心裏有數。

容量規劃有兩種形式,一種是容量預估,另一種是性能壓測

系統或者服務上線之前,首要進行容量的預估,一般做法是基於經驗,同時結合對業務的前景預期,先估算出一個總的調用量,比如 1 億的 PV,可能會有 10% 的流量落在購物車服務上,購物車服務就是 1000 萬的 PV,一次購物車訪問會產生 2 次數據庫調用,那麼它的關聯數據庫就會有 2000 萬的調用量。這樣,基於圖上從左至右,層層分解,可以獲取到每個服務節點上攤到的訪問量,再結合運維部門的單機容量指標,就能估算出整個集羣需要多少的軟硬件資源。

系統或者服務一旦上線,它的性能就開始處於不斷“劣化”的狀態,上線前預估的指標會越來越不準,這時候就需要通過線上性能壓測來對實時容量進行監控。做線上性能壓測也要遵循一定的規律,不是說一上來就做全鏈路壓測。同樣是基於上圖中的調用關係,線上性能壓測首先需要在調用鏈的末梢,也就是對數據庫或者緩存先進行壓測,以保證它們不是瓶頸,再對調用數據庫或者緩存的上一級服務節點進行壓測,然後一級一級往上壓測,最終覆蓋整個鏈路,實現全鏈路壓測

可見,全鏈路壓測的前提是單點壓測,需要先把單點壓測能力做好,才能做全鏈路壓測。

在壓測的時候,由於流量是模擬的,數據也是“僞造”的,所以一定要做好隔離,各種各樣的隔離,尤其是數據的隔離。我個人不建議將“染色”的壓測數據和真實的線上業務數據共表存儲,最好將“染色”數據單獨表存儲,並通過分表策略進行區隔。

另外,額外說說自動化壓測這個事。古希臘哲學家赫拉克利特曾經說過:“人不能兩次踏進同一條河流”。隨着時間的流逝,任何事物的狀態都會發生變化。線上系統也同樣如此,不同時刻的同一系統的狀況也絕對不會一模一樣。所以每次性能壓測,都可能會遇到一些突發狀況,尤其是在負載特別高的極限狀態下,甚至會遇到一些以前從未出現的狀況。壓測系統雖然做了數據及流量隔離,但所有的預防策略都是基於已知的知識結構來構建的,它不一定能防控住這些新狀況,樂觀一點,就算你控住了 99% 的突發狀況,只要漏掉 1%,就可能導致整個線上服務失控。這時就需要人工介入來判斷,並有針對性的進行處理。所以,全自動化、完全無需人工介入的壓測在我看來還不太現實。從我的經驗來說,在線性能壓測是個“苦活”,需要提前發公告、全員戒備、時刻關注監控指標、有時候還要通宵搞,總結起來就是:智力密集型 + 勞動密集型 + 人肉密集型

以上就是性能規劃,包含了容量預估與性能壓測兩大能力。

服務線上治理之故障定界定位

線上的故障定界定位應該是我們每天做的最多的事情。分佈式環境下的故障定界定位,最有效的工具就是動態調用鏈路跟蹤,這應該是沒有疑義的,不管你是使用開源的 Zipkin,SkyWalking、PinPoint、CAT,還是使用商用的聽雲、AppDynamic 或 NewRelic 等等。

調用鏈本質上也是基於日誌,只不過它比常規的日誌更重視日誌之間的關係。在一個請求剛發起時,調用鏈會賦予它一個跟蹤號(traceID),這個跟蹤號會隨着請求穿越不同的網絡節點,並隨着日誌落盤。日誌被收集後,可以根據 traceID 來對日誌做聚合,找到所有的關聯日誌,並按順序排序,構建出這個請求跨網絡的調用鏈,它能詳細描述請求的整個生命週期的狀況。

動態調用鏈要用的好一定是需要和監控大盤相結合。介紹一下我們的使用經驗,我們在很早之前就根據 Google 的那篇 Dapper 論文構建了動態調用鏈跟蹤體系,在我們的監控大盤上有很多的點可以進入調用鏈:

  1. 我們有一個單位時間段內異常最多服務的 TopN 排序列表,點擊列表上的任何一個服務,會打開這個服務這個時間段內所有異常的列表,再點擊列表上的每一個異常,就會打開這個異常所屬調用鏈,進行故障分析。
  2. 可以利用監控大盤,監控大盤上有很多“毛刺”,這些都是系統的一些異常點,點擊任何一個“毛刺”,會將“毛刺”所在時間段內的請求以“散點”的形式列出(可能會基於請求數量做抽樣),“散點”的顏色代表了不同的狀態,有的成功,有的失敗。點擊任何一個“散點”,就可以進入這個請求對應的調用鏈。
  3. 針對核心服務的異常有專門的監控表格,會列出最近發生的核心鏈路服務上的異常,點擊這上面的任何一個異常,也可以進入對應的調用鏈。

以上就是基於動態調用鏈進行線上故障定界定位的常用模式。

服務線上治理之生命週期管理

我們目前使用螞蟻金融雲提供的 SOFA 分佈式服務框架,針對服務的線上生命週期管控的能力也是基於螞蟻金融雲的能力來構建的,螞蟻金融雲在它的雲上彈性計算資源的基礎上,通過整合資源編排及資源調度的能力,構建了微服務的綜合管控平臺,通過這個平臺,可以比較方便的進行服務的上線、下線、擴容、縮容等操作。

我們將雲下的研發流水線和雲上的服務管控能力進行了打通,實現了從線下的產品設計、服務應用開發、服務應用構建,到雲上的服務應用部署、監控與運維的一體化聯動。

由於我們是做金融的,屬於國家強監管行業,安全合規在研發工作中佔了很大的比重,所以研發流水線中增加了很多審覈及安全校驗的環節,這也客觀導致了整條流水線會比較重,這是我們和一般互聯網公司的區別。

微服務整體架構治理 在傳統企業級開發中,一般遵循先架構設計再開發的協同聯動原則,但在服務化架構下,由於原來的單體系統被拆的很散,傳統架構師的職責更多的被分散到一線的研發團隊,由開發人員來承擔。看起來,貌似架構師的職責被減弱了,而且由於服務的粒度比一般應用小,架構的工作好像沒有以前那麼重要了。

實際恰恰相反,在離散化體系中,更要加強對架構的管控,以防止整體架構的劣化。與傳統的“架構先行”模式不同的是,服務化下的相當一部分架構工作被“後置”了,成了一種事後行爲,也就是說,架構度量和優化的工作會大幅度上升。這裏我們就主要討論如何通過服務之間的調用關係來針對服務化的整體架構進行度量和治理。

上圖是線上服務集羣服務間的調用關係總圖,它可以通過動態調用鏈的彙總來獲取,目前大部分公司都是這麼幹的。但使用動態調用鏈有個很大的缺陷,即調用鏈只有在運行時才能生效,而且,必須是有埋點並實際發生的調用才能被監控和採集數據,不管這個埋點是手工埋點還是自動埋點。而對於一個複雜的平臺或大系統而言,存在大量的冗餘分支和異常處理邏輯,這些分支及邏輯,往往需要在特定場景下才會被觸發,甚至可能永遠都不會被觸發,所以通過動態調用鏈抓取的這個服務之間的調用關係是不完整的。爲此,我們除了使用動態調用鏈,還開發了靜態代碼掃描技術,通過代碼之間的調用關係來生成這個調用關係圖,通過這種方式可以有效彌補動態調用鏈的不足。

有了微服務間的整體調用關係之後,我們就可以對微服務的調用質量進行深入的分析,所有的分析都建立在這個圖形的基礎上,因此我們會使用圖論的相關算法。

服務是分層的,好的服務調用關係一定也是分層的,層層往下推進,最終形成一個有向無環圖(DAG)。因此,可以對調用關係圖進行閉環檢測,如果檢測到如圖上 G 點到 B 點這樣的迴環調用的話,說明調用關係有問題,需要進行優化。這種迴環調用也許現在無感,但難保未來哪天就會由於一條旁路邏輯導致死循環。

另外,還可以對整個調用網絡進行遍歷計算,找出所有調用深度最深的調用鏈,如圖上紅色標註出來的調用鏈。我們知道,對跨網絡的調用訪問,涉及到的網絡節點越多,穩定性越差。因此,可以將所有調用鏈路最深的這些鏈路找出來,並按調用深度進行 topN 排序,重點對排在頭部的調用鏈分析它的必要性及合理性,看是否可以對調用深度進行縮減和優化。還可以找出整個網絡中被調用最多的服務節點,比如圖上的 F 節點。從調用關係上來說,它是被依賴最多的節點,自然是最重要的節點,作爲樞紐節點,在運維等級上需要重點保障。當然,實際應用中,我們還會加上調用量這個權重來綜合判定服務節點的重要性。

隨着架構的不斷演進,可能有些服務節點再也不會有調用關係了,比如圖上綠色的 L 節點,這些節點再不會去調用別的服務節點,別的服務節點也不會來調用它。這類被找出來的“孤零零”的節點,可以考慮對它進行下線處理,以釋放資源。

以上所有的度量和治理都是在這個調用關係圖的基礎上進行的,所用的算法也是圖計算(圖論)中的常用算法,包括 BFS、DFS、PageRank 等等,大家如果嫌麻煩,可以找個圖數據庫,比如 neo4j,這些算法已經集成在它的基本查詢能力中。

金融複雜數據資產體系下的數據治理實踐

接下來介紹天弘在數據資產方面的一些治理實踐。

由於業務迭代等歷史原因的影響,天弘共形成了三套數據應用及技術體系。

前面介紹了,圍繞餘額寶這支基金已經形成了一個完善的技術生態體系,這套體系每天會產生大量的數據,包括和支付寶的交易對賬數據、系統的增量數據等等。針對餘額寶的海量數據的存儲、分析、消費,我們專門構建了一套雲上的數倉來支撐,我們稱之爲電商大數據中心,主要採用螞蟻金融雲上的 ODPS+DataWorks 這套技術體系來構建。它的整個模型的設計完全按 ODPS 的方法論來設計,ODS 數據會按 DWD(明細數據)、DWS(彙總數據)兩層結構來進行彙總。彙總後的數據會根據不同的用途分門別類進行存儲,比如,用於離線分析的,會被存儲到 ODPS 中;用於實時分析的,會被存儲到 ADS 中;主數據或者供業務使用的數據,則會被存儲到 RDS 中。數據整理好之後,我們就可以在上面進行餘額寶銷售情況的分析、流動性分析、或者在其上做一些特徵工程分析和數據打標工作,以便做一些精細化的用戶運營,這是我們的電商大數據技術體系。

天弘除了餘額寶這支產品外,還有其它幾十上百支的基金產品,針對所有基金產品的銷售數據的分析也必須有相應的數據支撐手段,這部分工作主要由我們數據中心在負責,數據中心構建了一套 Hbase 技術體系的數倉來支撐所有基金銷售系統中的賬戶、資產、交易數據的抽取、存儲和分析,這套數倉採用的是典型的維度建模法,所有的基礎數據最終會被彙總成各個主題下的寬表、維表及事實表。這套數倉主要用來生成針對銷售的財務分析報告、監管報送報告等等。公司各業務線都在使用的報表中心也是在這套數倉基礎上構建的。

以上兩套數倉主要面向的是基金銷售。基金公司最核心的兩大業務,一個是基金銷售,另外一個是投資,投資是專業性很強的技術活,哪支股票或債券值得買,什麼時候買入,什麼時候賣出,這些都需要有數據的支撐,所以投資研究團隊也建了一個雲下的 Oracle 數倉,會將企業財報、行情數據、輿情信息等相關數據灌入這套數倉中。由於指標維度特別多,這套數倉採用了 cube 建模,利用雪花模型最終構建了一個非常多層的數據集市,再基於這個數據集市進行各個投資領域的分析,包括股票及債券的信用評級,持倉分析、企業經營健康度的跟蹤預警等等。這套數倉總的數據量並不是特別大,它更偏向傳統的 BI 分析,但指標維度要遠超前兩套數倉。

以上是我們目前主要使用的三套數倉,面向不同的業務領域。但多套數倉的存在也相應帶來了一些問題,首先是重疊度高,維護成本也較高,畢竟技術體系都不一樣,學習門檻較高,相關數倉使用團隊很難進行交叉支援;多套數倉的存在,客觀上也限制了數據在公司內部的流動效率,一個數倉的使用者要使用另外一個數倉的數據,需要對應數倉維護人員的支持,數據使用成本較高;多套數倉也容易導致數據口徑不一致,數據標準不統一;數據質量和安全方面的管控也很麻煩。

數據治理目標

爲了解決以上問題,我們在 17 年底立了一個數據治理的項目,希望通過建立統一的實時數倉,來統一公司內部的多個數倉的數據指標、數據模型和數據,以形成公司的統一數據視圖,並構建相應的數據門戶、數據服務接口,結合數據質量及安全管控,最終實現數據在公司內部更好的流動和分享,發揮數據應有的價值。通過數據治理工作,我們希望降低數據的總使用成本,提高數據開發的效率,並構建公司一級的大數據技術體系。

數據治理策略

數據治理是一項複雜的體系性工程,其中包含了數據存儲,ETL、任務調度、數據質量及安全管控、數據門戶及數據接口,以及在此基礎上的一整套方法論。

天弘本質上是一家金融公司,由我們自己獨立去構建這麼一套數據治理體系明顯不現實,好在市面上有不少相關產品,因此,一開始我們定的策略是“借力“,希望藉助外部力量來完成這個工作。我們評估了一些有代表性的數據治理產品及數據中臺產品,綜合分析後發現,單純落地一套數據治理或數據中臺的技術體系並不難,難就難在對現有數據指標、模型的遷移工作上。指標和模型是和業務息息相關的,對其進行遷移首先必須全方位的瞭解業務,試問又有誰能比我們自己更瞭解業務?這個工作我們自己都做不來的話,指望別人就更不現實了。

綜合評估之後,我們最終決定還是自己動手,尤其是要將模型的設計牢牢掌控在自己手中,自力更生爲主,同時輔助使用一部分外力。

由於數據治理工作體系複雜,需要長期迭代和優化,而且前期需要構建包括統一數倉在內的基礎設施,因此不能完全的業務需求驅動,必須將基礎設施的構建工作也提升到和業務需求對等的水平,才能保證底層能力不缺失。對於一些短期內很難構建完善的能力,比如數據血緣的梳理能力,我們會使用一些臨時方案來替代,再在未來能力成熟時進行優化或替換。

數據治理的最終目標是要保證數據的一致性、準確性,這需要一整套的流程規範來保障。流程規範如果只是存在於紙面上,是很難落地的,必須通過技術手段來強制進行貫徹。同時,還需要構建一套知識庫,來維護和沉澱所有指標、模型的定義。避免數據干係人對同一個指標或者模型理解出現歧義和偏差,因爲一旦出現理解偏差,必然會導致數據的不一致性。

以上就是我們在數據治理上的選型策略及實施策略。

數據治理架構及落地

來看一下數據治理工作最終落地的整體技術架構。在整個技術架構中,重點開發了 3 個能力,第一個是元數據管理,用來管控模型;第二個是解析代理層,用來隔離模型和物理數據;第三個是流程 / 工單模塊,用於保障數據管理及開發規範的落地。

我們希望通過模型,將頂層使用數據的用戶(或系統)和底層的物理數據進行嚴格的隔離,併爲此開發了完善的元數據管理能力,其中包含了指標管理、維度管理、模型管理、數據表管理這四大管理模塊。同時通過數據門戶中的數據地圖,創建相應的數據域,數據域下掛主題,主題下再掛指標、模型、數據表,通過這樣的一種樹狀結構,可以讓數據使用者快速的檢索和定位他所需要的模型。由於用戶主要接觸的是模型,因此必須保證模型的完備及準確,我們推薦使用者通過平臺提供的元數據管理能力來構建和使用模型及數據,這樣就能很好的管控模型。如果由於一些特殊原因,導致不得不使用 SQL 或者 Python 這類的腳本來構建物理表的話,我們也會通過一些輔助工具進行腳本的反向解析,以識別出模型;如果識別不了,就通過工單流程對腳本進行嚴格審覈,並在流程環節中由特定數據開發人員將模型補全,以保證模型不發散。

雖然用戶接觸的都是模型,但在執行數據查詢或變更操作時,還是要轉換成可執行的 SQL、HQL 等腳本。這時,就需要依託解析代理層來做這個工作,通過它的模型解析器,將模型轉換成可執行腳本;再通過一個異步任務調度服務集羣來進行長時間的數據查詢或變更操作。

由於通過模型隔離了底層的物理存儲,所以在存儲的選擇上就能很靈活,可以根據數據的熱度及數據量的大小來選擇不同的存儲服務,存儲這層主要通過數據適配器來負責。

模型的嚴格管控帶來了一系列的好處。首先,比較容易進行安全控制,能夠進行從數據域、數據主題、一直到數據表、字段一級的授權控制。基於模型也很容易識別出數據血緣,可以清楚的知道數據來自於哪,存儲在了哪裏,又被哪些第三方系統所使用。完整的數據血緣有助於控制指標的聯動影響,因爲指標之間往往由於數據的關係產生關聯,一個指標變動之後,可能會影響到其它指標,可以通過數據血緣來識別指標影響的範圍,以實現更精細的 ETL 調度策略。

通過治理工作構建了較完善的質量管理機制,通過批處理引擎可以定期運行一系列預定義的檢查規則,進行“髒數據”的檢測,並根據檢測結果自動生成質量報告。

爲了嚴格落地數據開發規範及數據使用規範,還在數據門戶中引入了流程引擎,基本上實現“一切皆工單,一切皆流程”。所有的數據使用申請,開發申請都需要在數據門戶中發起工單,並走相應的審批流程,可以說,流程是落地規範的最好工具

對於第三方系統的數據應用需求,我們同步提供了數據服務接口,提供“推”和“拉”這兩種數據共享方式。

最後,說一下如何讓企業的數據真正成爲數據資產。一方面,我們要持續的進行數據治理工作,以保證數據的一致性、準確性、實時性,讓數據有較高的質量,並降低數據的使用難度;另外一方面,也需要不斷提高人員對數據的重視程度。

因爲數據看的到但摸不着,所以很多人容易在本能上輕視它,一種有效的做法是對數據相關的工作進行收益度量。比如說,數據開發團隊幫助業務部門做了一個數據打標的工作,可以要求業務部門必須對這個數據開發工作的收益進行評估,比如幫助業務部門提升了 10% 的新客轉化率。這樣,通過定量的價值度量可以讓大家直觀的體會到數據及數據開發工作帶來的收益,長久以往,就能不斷的提高對數據的重視程度,真正做到將數據視作一種有價值的資產。

高效團隊協同模式及治理

最後,介紹一下我們在團隊協同方面的一些治理實踐,這部分是前面服務治理內容的延續,主要針對的是線下環節的治理。

服務化之後,每個團隊負責一部分的服務,經常一個業務會涉及多個團隊之間的協同配合,如何讓團隊之間的協作更高效,我們也做了不同的嘗試,從綜合效果來說,敏捷模式會更適合一些。以我們移動平臺團隊舉例,目前採用兩週一迭代、固定發版的模式,同時每個迭代之內,採用“火車發佈模式”,實行班車制,準點發車。這樣,其它協作部門在很早之前就能大概知道我們的發佈計劃,產品方面也大概知道要把需求放入哪個迭代中。這種模式能夠有效降低部門間的溝通成本。在每期工作量評估時,一般會預留一些工作量 buffer,以應對臨時性的需求,這類需求不受版本約束,按需發佈。如果這個迭代週期內沒有緊急需求,我們會從 backlog 中撈一些架構優化的需求來填補這些 buffer。

爲什麼會持續有一些架構優化的活呢?因爲經常有一些緊急需求,使用正常開發方案可能無法如期上線,但業務又要的比較急,必須用一些應急性的臨時方案先上線使用。這種時候,我們會同步創建一個架構優化的任務放到 backlog 中,等後續有時間再安排若干個迭代週期將這個臨時方案進行重構優化,以防止臨時方案變成長期方案,導致整個架構被腐化。因此我們的 backlog 池中,總是存在這類的架構優化任務。

對每個迭代而言,最不可控的就是 UI 的設計了。UI 設計感性因素更多,可能會反覆修改,不像程序代碼那麼明確。所以,我們一般不將 UI 設計納入迭代中,而是將其作爲需求的一部分,在每個迭代開始之前的工作量評估中,要求必須提供完整的 UI 物料,否則不予評估工作量,此需求也不會被納入迭代之中。

團隊協同質量度量及治理

對團隊的協同效率同樣需要進行度量和治理。我們採用數據驅動的精益看板方法,持續採集每個迭代中各個階段的過程指標事件,比如任務什麼時候完成設計、什麼時候進入開發、什麼時候開發結束、什麼時候進入測試… 等等。這些過程指標被彙總後,會在其基礎上製作出精益看板中的幾大典型報表:

  • 韋伯分佈圖
  • 累積流圖
  • 價值流圖
  • 控制圖

通過這幾個報表,結合精益看板就可以對需求流動的效率進行持續的評估,看研發管道是否有堆積、是否有阻塞、並進行實時的干預和治理。注意,這裏評估的是協同的效率,而不是研發資源的利用率,對研發資源的利用率,我們有另外的度量指標和報表。

舉個例子,比如說,在看板上看到“開發完成”這個步驟堆積了一些任務,由於敏捷協作是基於“拉動”式的,說明“測試”這個環節的處理能力出現了問題,才導致前置的“開發完成”環節形成堆積。這時候就需要去了解測試究竟出現什麼樣的問題、問題原因是什麼,並解決問題,以保證整個研發管道的流動是順暢的。

每個迭代持續的進行精益看板的數據分析和度量,並通過治理策略進行不斷的改進優化,可以讓我們的研發協同越來越順暢。

開發質量度量及治理

針對代碼質量的管理,常規的做法除了代碼的 codereview 外,一般還會使用 Checkstyle,FindBugs,Jtest 這類靜態代碼掃描工具來做代碼的缺陷掃描。但這類工具只能掃描單個類或文件的缺陷,對跨類的多層循環嵌套這類的問題就無能爲力了。爲此,我們開發了針對這類缺陷的靜態代碼掃描工具,這個工具和前面介紹的掃描代碼的靜態調用鏈路的工具實際上是同一套。除了深層的代碼缺陷外,利用這個工具還可以對代碼的註釋完備性及註釋密度進行檢測,畢竟人員的流動是客觀存在的,開發人員遲早要將自己的開發代碼移交出去,完備的註釋可以降低新人接手的難度。

除了代碼質量之外,還可以結合線上 bug 的種類和數量,來綜合評估開發人員的開發質量。因爲,代碼是人寫的,bug 也是人製造出來的,通過結合開發人員開發的代碼的質量,及他的產出物產生的異常等級(類型及數量),對開發人員的開發質量進行綜合度量。我們這裏採用相對指標,而不是絕對指標,防止陷入“做得越多,錯得越多”的怪圈。當然,實際中還會結合其它的指標,但這兩個是最主要的指標。通過這兩個核心指標,可以生成研發人員開發質量綜合評估報告。

進一步彙總個人的質量綜合評估報告,可以獲得針對團隊的開發質量綜合評估報告。這兩個報告本質上就是個人及團隊的研發質量“畫像”,完全可以作爲個人及團隊 KPI 考覈的重要參考。在此基礎上,還可以通過這兩個報告的變化趨勢(時間縱比),來促使開發人員和開發團隊不斷進行開發質量的改進和開發技能的提升。

測試質量度量及治理

服務化架構下的測試治理的兩大核心訴求:一是提高測試的覆蓋度,具體說就是提高需求覆蓋度、代碼覆蓋度、頁面覆蓋度;二是降低測試用例的維護成本。

先討論測試覆蓋度。

需求覆蓋度,可以通過服務這個維度來對需求及測試用例進行關聯,找出每個需求所對應的單元測試用例、自動化測試用例、手工測試用例,還可以把多個開發迭代週期的這些指標進行時間維度的縱比,以得出需求覆蓋度的變化趨勢。

代碼覆蓋度,有很多的工具幫我們來做,比如 contest 或者 JaCoCo 這類的工具,這裏不再贅述。

頁面覆蓋度,可以將每次集成測試中調用的頁面以日誌的形式記錄下來,再通過日誌的聚合分析,結合工程源碼的掃描,兩廂一比較,就可以統計出哪些頁面是沒有被覆蓋到的。

測試用例的維護成本分兩塊,一塊是新增用例的維護成本,這個比較好度量;比較麻煩的是存量測試用例的變更度度量,我們採用相似度匹配算法,先算出存量測試用例前後兩個版本代碼的相似度,再換算成變更度。

通過對測試的這兩大類指標的不斷度量和治理,可以實現測試工作的整體“降本增效”。

分佈式調測能力構建

在服務化的過程中,研發最大的痛點一定是調試。原來單體應用中的服務被拆分到不同團隊,並部署在不同的服務器上,而本地只有一個服務接口。這時候要做調試,要麼做 P2P 直連,這需要搭建不同開發版本的集羣,成本較高;要麼做 MOCK,採用傳統的 MOCk 手段,要寫一堆的 MOCK 語句,比如用 mockito,你要寫一堆的 when……thenReturn…. 的語句,耦合度非常的高。

我們利用分佈式服務框架提供的過濾器機制,開發了一個 Mock 過濾器,通過 Mock 數據文件來詳細定義要被 mock 的服務的名稱、入參及出參。這樣,當請求過來時,將服務名及入參和 mock 數據中的定義進行比對,結果吻合,就直接將 mock 數據文件中的出參反序列化後作爲服務的調用結果直接返回,同時遠程調用的所有後續操作被終止。這樣,通過 mock 數據模擬了一個真實的遠程服務。通過這種方式來構建服務的 mock 能力,我們就不需要寫一堆的 mock 代碼了,而且整個過程對業務邏輯來說毫無感知,完全把 mock 能力下沉到底層的服務框架。

另外,爲了有效降低製作 mock 文件的成本,我們開發了一系列輔助工具,可以基於服務接口直接生成 mock 文件的框架。我們還基於服務框架的過濾器機制開發了“在線數據抓取過濾器”,它可以將指定的服務請求的入參和返回結果都抓取下來,直接寫成 mock 數據文件。通過抓取方式獲得的 mock 數據文件,往往有更好的數據質量,畢竟反映的是更加真實的業務場景。不過,這裏還有一個合規性的問題,一定要做好數據脫敏的處理工作。對於我們,目前只在測試環境中進行數據抓取操作。

我們的綜合調測能力是綜合 P2P 直連和 Mock 兩種方式來共同構建的。在項目迭代的早期,前端團隊和服務端團隊,中臺開發團隊和後臺開發團隊會先定義接口,再基於接口直接生成 mock 文件,這樣大家就可以並行開發。開始時,服務都沒有開發出來,mock 比例是最高的;隨着迭代的進行,服務被不斷開發出來,並部署到線上,這時,P2P 直連調測的比例會上升,Mock 的比例會下降;一直到集成測試時,只剩下 P2P 直連的模式,沒有 mock 了。

通過以上的調測能力構建,可以有效改善服務化架構下團隊的開發效率,而且團隊規模越大,這種調測體系的效果越明顯。

以上就是我這次分享的全部內容。

作者介紹

李鑫,天弘基金移動平臺團隊任技術總監兼首席架構師,主要負責天弘移動直銷平臺的整體技術架構和技術團隊管理;在此之前,在華爲的中間件技術團隊,任六級技術專家,主導了多款華爲軟件的雲計算產品的規劃、設計、構建及落地工作,包括 APaaS、ASPaaS、服務治理平臺、分佈式服務調測框架等幾款產品;更早之前,在噹噹網的運作產品中心做技術負責人,主要負責電商中後臺的倉儲、物流、客服等系統的重構優化及技術管理工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章