一、痛點
讓我們先來談談DataWorks目前遇到了哪些痛點,這些痛點是倒逼着我們進行技術變革的源動力。
1.1 沉重的曆史包袱
首先要提的就是曆史原因遺留的各種問題,DataWorks曆史上多個版本同步開發,前後端技術棧多次變革,應用一旦上線就很難廢棄,一個對外暴露的api,很可能是5年前開發的,但依然有業務在依賴,通常情況下連這些古老業務的負責人都找不到了。當我們的服務正常運作的時候,無人搭理,一旦下線,則可能不知道從哪兒跳出幾個使用者前來投訴。頁面上的功能同樣如此,有時候隻是過去不知道哪位同學開發中引入的一個bug,但也因為我們的使用者基數龐大,而變成了真理。曆史上曾經出現過的隐藏的很深且使用者寥寥的功能點都有自己的忠實擁趸,一旦被我們的開發不小心忽視而做丢了,就會迎來投訴和工單,是以DataWorks平台不愧是千錘百煉磨練出來的大資料開發平台的标杆,樸素的界面之下隐藏了無數細緻入微的功能點。如果想重造這麼一個被阿裡巴巴經濟體無數資料開發工程師驗證(折磨)過的資料開發平台,都要好好考慮一下這十年來我們的平台到底經曆過了什麼。
1.2 複雜的軟硬體環境
DataWorks面臨的運作環境放眼整個阿裡巴巴經濟體都是及其罕見的複雜,為了混合雲(即專有雲)這種私有獨立且封閉的環境,三合一版本之後我們必須放棄依賴彈内成熟的中間件體系,隻能尋找那些同樣在三個環境下都存在的技術來支撐。也是以,很多在某個環境下缺失的依賴,如果我們無法用開關的方式搞定,或者我們判斷其複雜度不高,就會通過自研或者去依賴一些開源的體系來解決問題。而公有雲上各種網絡環境的問題幾乎都要靠人肉去排查,從每天居高不下的答疑量上就能看到我們受環境問題的影響是多麼耗費人力。除此以外,前不久中美貿易戰帶來的影響也傳遞給了DataWorks平台,運作環境需要比對國産晶片,我們的程序不但要運作在X86指令集上,同樣也要能運作在基于ARM指令集的國産晶片上。同時為了滿足部分中小企業使用者的購買欲求,靈活化也是我們需要去裁剪設計的。

DataWorks平台雖然龐大且複雜,但在種種更加複雜的軟硬體環境下,也同樣需要能夠做到靈活輕便,便于随時随地的拆散組合輕裝上陣,以滿足不同業務場景下使用者的期望。因為挑剔的使用者一貫希望用最少的錢購買到最合适的解決方案,DataWorks的競争力顯然也要從靈活且具備演變能力上尋找未來。
1.3 牽一發而動全身
工程之間的複雜關聯一直是傳統SOA(Service Oriented Architecture:面向服務架構)發展到一定規模後的噩夢,無論最初的設計是多麼合理,多麼領域清晰,一旦經曆需求的積累,規模的擴張,人員的交替,都将逐漸或多或少的面臨着邊界模糊的問題。最典型的例子就是單體服務之間的RESTful類型的API,往往這些API的Schema隻能增加元素而不能減少,因為被依賴者并不知道有多少其他服務正在依賴這個接口,也許某一天某個服務從沉睡已久的伺服器中被喚醒,結果發現你的API的Schema變了,那麼一定會把你喊回來修回原來的樣子。前後端分離架構下,這類問題更加突出,是以有的前端同學為了減少schema變動帶來的影響,幹脆讓後端透傳一個大字元串,即使裡面夾帶了私貨,也不會使得頁面莫名崩潰。DataWorks平台也正在經曆着這一過程,發展到一定規模後,每個功能的改動都要小心翼翼,生怕對其他子產品造成未知的影響,或者有時候我們需要把大量時間投入在調研清楚改動帶來的影響上,就算這樣嚴防死守,也依然可能有漏網之魚,最後功虧一篑,一個故障單就可能把為之付出的努力付之一炬。
1.4 需求變更和頻繁釋出
除了工程架構上的問題,同樣存在問題的還有衆多開發者在合作方面産生的問題,gitlab幫我們解決了版本之間的代碼沖突問題,但并不能解決産品釋出周期上的沖突。當多個需求都要對外釋出上線,尤其在混合雲,需要按月為周期産出大版本,我們一邊要快速上線新feature,一邊還要按照類似瀑布模型的方式将這些功能打包進專有雲版本。彈内、公有雲、混合雲的釋出節奏截然不同,衆多feature按照不同的節奏要出現在不同的版本疊代中,過去的熔斷機制,更加劇了大家在視窗期集中釋出而産生的風險。在SOA中的一個單體服務上,N個開發者開發的M個feature,按照什麼樣的間隔組合釋出上線,使得釋出的節奏既不過于頻繁,也不會因為釋出頻次太少而使得版本跨度太大。如果這M個feature之間又存在依賴關系,則進一步放大了釋出頻次增減之間的沖突。
1.5 國際化帶來的問題
國際化的問題向來不簡單,時區、夏令時、語言、習慣、本地化圖示等等,對于DataWorks這樣一個遍布全球20個region的平台來說,這裡面的水深的很。我們團隊在國際化方面沉澱很多積累,并且将這些優秀的經驗對外開源:
https://github.com/alibaba/react-intl-universal。
1.6 依賴耦合
基于SpringBoot的Starter,我們提升了代碼的複用率,且對于Starter的精心設計,確定同學們自研踩過的坑不需要反複由不同的同學來踩。但是這畢竟是不同工程中的共同依賴,當這些Starter暗藏bug的時候,凡是使用到這些依賴的工程都将受其影響,甚至某位同學不小心在修改某個依賴甚廣的Starter的時候寫進了bug,就有可能觸發系統雪崩。
1.7 笨拙的灰階機制
我們知道搜尋引擎在不同的算法中尋找最優解的方法,是将這些算法灌裝到不同的桶裡,然後引流通過這些算法桶,通過各種名額的對比,将其中最優的算法挑選出來。這是一種基于架構設計的灰階機制,并不需要人為幹預流量的導向,從入口處進來的不同搜尋自然而然的就流過了不同的算法桶,随着海量的通路,最優解必然得以顯現。但是目前的SOA架構下灰階往往依賴于提前設計好的開關,DataWorks便是如此,當我們需要驗證某個功能是否存在問題,傳統的辦法是找到前端同學,讓前端設計一下開關機制,篩選一部分使用者進入到新設計的功能裡面,經過一段時間的試跑和調整,逐漸把問題解決掉,同時對使用者的影響也可以控制在比較小的範圍。但這顯然不是一個可以反複的,随意的,自然而然的灰階機制。人為的幹預,為灰階而耗費的設計開發,使得一次灰階的成本居高不下,有些時候我們的同學甚至因為想避免麻煩,而忽視做灰階驗證。當我們想通過灰階來驗證的功能非常的局部,或者使用者無關,工作空間無關的時候,或者我們壓根不知道哪些使用者會使用到某些功能的時候,灰階機制也會在傳統架構下失效,即使我們想去設計,也無從下手。
對于SOA下單體服務來說,灰階無法借助于架構的設計,但是DataWorks平台下底層排程服務Alisa的Gateway叢集由于機器數量龐大,也可以實作基于架構設計的灰階機制,幾百台Gateway中,我們可以取出一小部分,部署待驗證的新版本,任務下發後通過不同版本的比對,尋找潛在問題。但這并非DataWorks平台後端的常态,幾乎所有單體服務并沒有部署到這麼多機器中,是以這也幾乎是大多數SOA的狀态,都面臨着不能基于架構設計,而要基于人為幹預的灰階機制。
1.8 外部關聯服務的不确定性
外部關聯服務複雜多變,且不可靠不穩定,随時會當機或者網絡中斷,甚至是外部服務更新忘了通知我們,進而導緻故障頻繁。這一點對于資料內建這樣一個在幾十種引擎,數千個資料庫執行個體中搬運資料的應用來說尤其深有體會。為了應對外界服務的不确定性,我們将有衆多依賴的自身應用設計的魯棒性特别優異,然而這會增加我們自身代碼的邏輯複雜度,偶然出現的問題也會被代碼的魯棒性掩蓋,問題如果不及時處理,就會逐漸積累,當所有出現故障的條件湊齊之後,一次性爆發一個P1級别的大故障。
1.9 緊缺的前端
DataWorks研發平台還面臨着前端人手不足的問題,這是富互動産品的研發團隊都面臨的共通問題。前端受制于互動的不同,樣式的迥異,業務的差別,以及研發同學各自對業務了解上的差異,以至于能夠複用的前端元件極其有限。在浩如煙海的前端類庫、元件、樣式中,能夠實作成本轉移的寥寥可數。在前後端分離,基于主流前端架構的設計模式下,相較于曆史上的前後端一體設計體系下的使用者體驗是有提升的,然而這都是基于前端開發同學辛勤的勞作,一點點的調整樣式和互動換來的成果,這裡從來沒有捷徑可走,而我們隻能寄期望于能夠複用前端開發同學的研發成果,讓每一次設計都不要成為隻使用一次的勞動。
1.10 其他
上面列舉的幾點當然不是DataWorks研發平台面臨的所有問題,還有一些不算那麼緊急的痛點經常時不時的會出來提醒我們。比如在實際日常工作中,我們常常希望能夠上一些實驗性質的功能,讓一部分使用者嘗鮮,通過埋點取得使用者的使用情況,給PD做參考,但這類工作量往往不小,是需要額外花費精力的。再比如,資料開發工程師提出的需求,經過PD的翻譯再經過研發同學的了解,往往就變了味,這時候某些有餘力的資料開發團隊就幹脆自己來實作,他們希望能直接在我們的平台上開發他們需要的功能,如果我們短期無法提供,他們就幹脆自己來做個門戶,集中自研工具集來滿足自己的需求。這些問題不一而足,都需要我們改變自己的架構設計,來迎合彈内外使用者的個性化需求。
二、合作與競争
DataWorks研發平台衆多功能涵蓋了資料開發工程師的日常工作,使用者在我們的平台上長年累月的伏案工作,對一些功能點的設計有自己的切身體感,而這些體感是我們平台的研發感受不到的。PD和我們的UED去收集需求去使用去親自感受,然而畢竟不是專職于資料開發本身,是以很難體會到資料開發工程師長期使用後的那種細微的挫敗感。再到細分的垂直業務市場,不同行業下如何使用我們平台,差異更是有天淵之别。面向金融,銀行,政府,大型國企,網際網路公司,傳統企業,民營,教育,等等,他們的用法都是完全不同的,有的行業甚至就不知道拿到DataWorks平台後該做什麼。使用者的需求千差萬别,使用者的心智也處于不同階段。
是以,在我們無暇一一顧及的領域,前方的傳遞團隊或者公司,使用DataWorks平台應用到具體的行業中,然後再将行業的專屬需求帶回給我們的PD進行分析。我們平台本身也會開放一些Api給予前方團隊包裝成産品提供給特定領域的客戶,幫助客戶解決實際問題。
新的産品規劃還在不斷制訂之中,引擎團隊設計好自己的産品也需要在DataWorks平台上降低使用者的上手難度,如果永遠隻是DataWorks平台的開發同學按照排期逐漸完成這些接入和訂制需求,平台注定難以持續發展壯大。是以,從前後端架構層面,從無數的合作和競争場景出發,都迫切需要我們進行一次針對自身的技術革命,徹底從SOA中解放生産勞動力,引入更多的使用者側的研發力量,幫助平台向更健全的方向發展。
三、架構的變革
任何一種技術的變革都是循序漸進的,這和Spring之父Rod Johnson秉持的理念是一緻的。他提出了“輪子理論”,也即“不要重複發明輪子”,這是西方國家的一句諺語,原話是:Don't Reinvent the Wheel。除此之外,通過長期的實踐後他在著作中總結闡明了循證架構的思想,即“沒有最好的架構,隻有最合适的架構”。這是架構界進化理論的雛形,意味着我們的架構要不斷的演進去配合多變的業務需求。
傳統的SOA下,服務趨向于穩定和集中,單體服務之間是平等的,或者至少在共通的結構上是類似的,服務與服務之間通過網絡通信進行依賴。SOA下每個單體服務可能是多個開發者圍繞着進行合作開發,是以替換任何一個單體服務都是一件傷筋動骨的事情,當有大的技術棧的變革,例如從WebX 3.0更新到SpringMVC,從SpringMVC更新到SpringBoot,人力成本消耗都是巨大的,更新周期動辄以年為機關,更不用說假設我們想用Go語言或者Python的Django架構來替換J2EE體系下已經設計好的web服務,這幾乎是不可能完成的任務。也意味着當我們進入了這個技術體系,就很難再從這套體系中脫身,更無從談起架構的演變和進化。
在傳統SOA下,提升工程效率的手段是極緻的代碼複用,凡是可複用的代碼,都抽取到二方包中設計成類庫讓不同的單體服務依賴調用。雖然配置越來越複雜了,但的确減少了“重複發明輪子”的事情。
還有一個辦法,是如我在2015年時候嘗試新的架構設計時候采取的方法,即:能抽象成二方包的抽象,不能抽象的通過自動化代碼生成工具自動生成。一套演練成熟的SOA架構工程,從目錄結構到配置組裝都幾乎是穩定不變的,即使有變化,也都是按照MVC三層架構進行微調,是以我們可以把一些無法抽象的,或者包含了複雜邏輯,需要靈活調整的代碼通過自動化代碼生成工具來生成,并且盡可能備援代碼的功能,讓開發者從生成的工程代碼中盡量做減法或者根據業務邏輯隻修改最少量的代碼,進而提升了工程的整潔度和開發效率。
除了代碼的複用,還有服務的複用,我們設計了一些中心化的單體服務,用于将複雜邏輯或啟動較慢或需要緩存,等等這樣一些功能封裝在這些核心服務中,進一步減少圍繞中心服務的其他應用的體量和複雜度,當然這也可能會引入單點可靠性的問題,但要確定核心服務的穩定可靠,在一定規模的服務體量下并非難事。
即便如此,SOA在效率上的提升依然是有限的,初期工程建立的快速高效并不代表長期業務開發後還能維持這樣的效率持續發展。前文描述的痛點逐漸展現且缺乏行之有效的解決辦法,開發者由于整齊劃一的使用同一套技術棧甚至同一套工程目錄樹結構,雖然在協同的時候更加默契,但也消滅了前沿技術在團隊内的賽馬機制。研發同學在一套逐漸古老落後的架構下研究怎麼壓榨出最後的效率和性能,但往往忽視了也許換個架構換個技術棧甚至換個語言,就會帶來質變。是以,當基于谷歌的K8S體系成長的生态圈逐漸成熟之後,遵循“沒有最好的架構,隻有最合适的架構”的思想,我們開始思考如何将DataWorks的技術方向轉向靈活多變的微服務架構。
3.1 微服務架構
提到微服務,理所當然要和雲原生關聯,所謂雲原生(Cloud Native),包含了如下三點:
1)DevOps
開發和運維不再是分開的兩個團隊,而是你中有我,我中有你的一個團隊。
2)持續傳遞
持續傳遞的意思就是在不影響使用者使用服務的前提下頻繁把新功能釋出給使用者使用。
3)容器化
容器化的好處在于運維的時候不需要再關心每個服務所使用的技術棧,每個服務都被無差别地封裝在容器裡,可以被無差别地管理和維護。
滿足上述三點的雲原生環境,對于微服務來說天然适配。當一個産品發展到一定規模,且具備了足夠體量,擁有數量衆多的子産品,以至于互動和依賴關系日益複雜,則微服務架構将為這樣的産品下的工程群帶來顯然易見的好處。本文不對微服務的基本概念和泛泛的正常做法做詳細介紹,網上此類文章汗牛充棟,這裡僅推薦兩本不錯的書《微服務設計》(前幾章概念講解還可以,後面部分一般)和《微服務架構設計模式》,前者适合初步了解,後者适合進階。本文僅讨論DataWorks在新的架構下的做法,從實踐中得真知。
對于DataWorks研發平台下衆多産品應用來說,微服務架構方向的改造也許不是能破解所有問題的萬能鑰匙,但一定是目前開發模式所遭受的病痛的解藥。
★ 3.1.1 認清自身
DataWorks研發平台屬于典型的PaaS應用,當然也有資料服務這樣的産品做到了SaaS層。傳統SOA遇到的痛點,以及将來我們要對客戶開放的定制化能力,需要借助微服務架構來應對,逐漸将研發重心從PaaS移向SaaS。
當我們采用基于K8S容器化的微服務架構之後,開發者可以在我們自主研發的微服務平台中內建DataWorks平台開放出來的基礎OpenAPI,也可以內建外部應用的API,在微服務中進行資料整合和業務邏輯的編寫,最終暴露出一系列在平台前端可通路的API,供前端功能子產品使用。在這個過程中,我們可以順便化解前文提到的一些痛點。
★ 3.1.2 解決痛點
以曆史包袱為例,我們可以逐漸将年久失修的,陳舊的SOA單體服務中包含的功能進行替換,将這個快變質的大餅切割成一個個低耦合的小餅,實作逐漸的更替,而非采用長周期的一次性整體替換。陳舊的工程不必再去發展更新,僅維持基本的運作,避免了整體替換帶來的周期長,故障多,復原困難的問題。而且我們可以很友善的通過金絲雀釋出來驗證新上的“小餅”是否成功替代了“變質大餅”中一小部分子產品的功能,通過藍綠部署将有問題的小餅快速及時的撤下,也可以做到通過ABTest來驗證哪塊小餅的性能更好、設計更合理。
再以個性化需求為例,當我們開放了和DataWorks業務耦合的微服務平台,具備自研能力的業務團隊(如資料/報表開發團隊)就可以借助微服務的設計,快速的将自己的需求設計到我們DataWorks平台後端,同時前端頁面我們也會留出“自留地”(下文描述的插件化)供業務團隊自行設計開發。引擎的接入同樣可以參照此模式進行,DataWorks下一部分子產品的接入可以更加的傻瓜化,比如檢查器,比如功能強大的自定義節點等,使用者根據文檔經過簡單的開發後就可以快速自主接入使用,但對于更加訂制的功能,例如目前ADB引擎正在DataWorks平台上進行的可視化建表部分的設計,由于複雜度很高,是以必須通過微服務對接前端插槽(下文描述)來進行開發,進而實作複雜業務邏輯的自主自助接入。
再來描述一下基于架構的灰階機制,在微服務架構下,可以輕松的實作藍綠部署,金絲雀釋出和ABTest,我們的微服務設計應該是盡量面向領域的(當然不太可能做到100%的面向領域),高内聚低耦合依然是單個微服務的設計宗旨。我們可以釋出多個版本的微服務用來測試某個領域的問題是否得到某方面的改善,也可以釋出多個完全基于不同架構甚至是不同語言設計的微服務,來驗證某個領域内誰是最優解。借助于基于架構的灰階機制,基于雲原生,這一切都将非常高效且可靠,即使出現問題,也可以快速撤下有問題的微服務,避免擴大影響。
還有其他一些痛點,不一一描述基于微服務架構的解法,比如牽一發而動全身的問題,在DataWorks平台全面建構到微服務架構上之後,這個問題自然就會消失。每個同學都可以分管多個面向領域的足夠小的微服務,當某個接口需要重新設計,不必立即替換老的接口,而可以将這個接口下對應的微服務低成本的重新設計,等待流量切換到新的微服務後,再逐漸下線舊版本微服務。再比如SpringBoot下由Starter引入的耦合性,到了微服務架構下,将會通過服務發現來解耦,不再需要通過代碼層面的依賴來耦合關聯。
★ 3.1.3 循證架構
再回過頭來講講本文還沒提及的一塊内容,我們的微服務到底是什麼?微服務當然不是一定要以微小為特征,它還是一個SOA,隻不過會更加輕量級更加面向領域。以機器人工廠為例,該産品有一個功能是讓使用者配置一些意圖跳轉到使用者自己設計的應答邏輯中,這部分正在擁抱微服務架構,完成上線後,使用者可以根據輸入來設計自己的應答微服務,且語言無關。這樣做還可以避免使用者的微服務在設計不良的情況下崩潰,不至于影響到其他正在運作的微服務,機器人工廠的這個場景也可以設計成FaaS,使用者隻需要編寫函數就可以完成自己的應答邏輯,且按通路量來計量使用情況。
機器人工廠應用微服務
DataWorks團隊設計的微服務平台,充分擁抱了現在大熱的Service Mesh,即服務網格,通過Mesh将一部分工作封裝在前置的微服務裡,這些系統級微服務與開發者設計的微服務運作在同一個pod裡,使得開發者設計的微服務更加簡單,Mesh更像是Spring架構下的HandlerInterceptor或者Filter,面向AOP程式設計的開發者擅長在工程裡開發攔截器和過濾器,到了內建了Service Mesh的微服務架構下,可以友善的使用系統級微服務替代一部分傳統攔截器的工作。比如登陸跳轉、權限控制、服務發現,比如限流、監控、日志聚合等等。
Service Mesh
讓業務專注于業務本身,避免諸如登入配置、日志配置等對工程開發的幹擾,同時我們還設計了不同語言的DMF(DataWorks MicroService FrameWork)架構群,幫助開發者快速上手微服務的開發。“沒有最好的架構,隻有最合适的架構”,将來我們也會開放DMF的開發設計,讓更多業務方貢獻自己的“最合适的微服務架構”。為了更好的支援和我們業務強相關的DevOps,我們開發了DataWorks微服務平台(DMSP:DataWorks MicroService Platform),用于管控微服務的部署和釋出,以及服務治理等其他運維工作。
3.2 前端的體系配合
前面提到的插件化指的是我們前端團隊設計的XStudio插件化方案,插件結合後端微服務,成為一套整體的解決方案,DataWorks平台的前端團隊希望基于此,嘗試探索出一套提升前端研發效率的方法論。XStudio插件化基于 single-spa 和 qiankun架構實作。該架構提供了多執行個體模式,插槽機制和可視化插件編排等重要特性,進一步提升了插件開發的效率。整套插件化的示意圖如下:
前端同學在基于XStudio插件化設計的頁面上,留好插槽,插槽裡面可以是一個按鈕,也可以是其他任意類型的元件,這個元件後面綁定一個微服務,我們可以将插槽裡面的内容連同後端的微服務一并替換,實作頁面功能的快速組裝,進而實作一次開發的多處使用。同時,插槽裡的内容也可以由業務開發團隊來提供,那麼業務開發團隊也隻需要自行設計前後端一體的這樣一個插件來放置到前端插槽裡,實作個性化需求的訂制開發。
在傳統的插件化設計裡,開發者們要麼提供一個遵循某種接口協定的二方包、要麼提供一系列遵循某種協定的API再由SOA架構向前端輸出。這帶來的問題要麼是對SOA服務有侵入,要麼影響了SOA服務整體的安全性和穩定性問題,要麼受限于程式設計語言、要麼毫無靈活性,而微服務&插件化完美的解決了這類問題。
對于需要占用更多頁面空間的設計,我們可以将大片區域設定成可替換元件,比如上圖的編輯器部分,讓使用者自行替換掉這片區域的頁面内容,跟後端一個或者多個微服務關聯起來嵌入到DataWorks的前端頁面中,友善業務團隊實作更複雜的自定義業務邏輯。目前ADB的可視化建表部分的設計正是遵循了這套方案,由ADB引擎團隊自行開發接入DataWorks平台中。
同時,前端體系中還有重要的一環是受訪的資料監控和報警,我們設計了各種次元的報表和名額監控,無論是自己的業務還是外部業務團隊寫進來的元件,不用多寫一行代碼,都可以通過“自動化全量埋點技術”,觀察和了解元件的使用情況。
熱力圖
3.3 插件的運作
目前我們已經将部分前端基于XStudio架構的元件與後端微服務配合起來實作了插件化封裝,比較優秀的如Terminal,DWEditor,目錄樹,檢查器等插件。以Terminal為例,該插件設計完成後,插入到不同的Studio中對接不同的引擎,并且可以根據使用者的使用情況自動拉起或者銷毀容器執行個體,進而節省運作資源。
Terminal插件接入到多個引擎,無論是前端還是後端的微服務都不用針對引擎進行額外的開發,進而實作開發效率的提升。插件化的封裝設計,不僅可以節約開發資源,而且可以實作多個應用集中使用一套微服務的目的,而彈性編排和自動擴縮容機制保證了服務的性能,同時不至于浪費機器資源。
Terminal插件的架構設計圖
此外,基于微服務架構,我們還可以建構SaaS的一些實作,例如FaaS、BaaS(Backend as a Service),以及BFF(Backend For Frontend)。以BFF為例,移動端的DataWorks應用BFF後,可以減少移動端H5頁面的網絡消耗,将後端多個微服務提供的接口通過Gateway組裝後提供給移動端,實作微服務的聚合。如果通過BFF做了SSR(Server Side Render:頁面同構,相當于在伺服器端直接渲染成html輸出到浏覽器),則可以進一步降低移動端的渲染性能消耗。
★ 3.3.1 DataWorks微服務平台
前後端一體基于DataWorks業務的插件化,也是我們堅持要自研設計開發DataWorks微服務平台(DMSP:DataWorks MicroService Platform)的重要原因。DMSP打通了前端元件的釋出和後端微服務的綁定關聯,通過Swagger這樣的技術手段成功使得前後端在部署後可以迅速成為一個業務插件。讓團隊的前後端都可以在DMSP裡面實作DevOps,以持續傳遞的方式源源不斷的将新功能釋出給客戶。
尤其值得說明的是,DMSP同樣是針對三大環境的,即彈内、公有雲和混合雲,插件開發完成後,我們要通過DMSP持續傳遞到公有雲多達20個region的環境中,還要能夠實作微服務在專有雲的統一打包部署。并且,DMSP還要讓開發插件的同學盡量對複雜的外界部署環境無感。
未來我們期望整個DataWorks平台的大部分頁面内容都基于插件化設計,進而解決前文痛點裡面提到的問題:“靈活輕便,便于随時随地的拆散組合輕裝上陣”。架構驅動的不僅僅是開發模式,而且勢必還将影響到整個産品的藍海。
四、構造生态
構造生态的重要前提是要有競争,要有優勝劣汰,構造生态的同時就是在構造可以演變,可以适用進化論的技術體系。作為“循證架構”的升華,微服務架構顯然在進化方面更勝一籌,循證架構是一種自上而下用進廢退的技術演進路線,而微服務架構則是一種自下而上優勝劣汰的技術演進路線。容器化實作了語言無關,架構無關,每個微服務都被無差别地封裝在容器裡,進而可以針對一個功能開發出多種微服務,類似算法桶的優選機制,從這些完成同一個功能的微服務中挑選出最優解。在理想情況下,無需上層架構師的主動幹預,應用就可以在一段時間的進化後自組裝成最佳的實踐。當然這隻是理論上的情形,我們身處的現實世界受很多外界因素的幹擾,實際情況下,受限于開發者的技術素養、外界依賴的參差不齊,甚至是受限于KPI的導向,都将使得這種理想下的最佳實踐無法達成,但微服務架構給予了我們可以通過團隊的協作和努力,進而無限接近理論中的最終解的能力。
在微服務架構下,前文提到的垂直業務的定制開發也将成為一種可能性,面向行業的傳遞團隊可以利用DataWorks平台提供的插件化能力,為客戶訂制完全适配行業特征的智能研發平台。進而在DataWorks研發平台上營造一個有活力的創新生态圈,為客戶提供更加豐富多彩的選擇。架構将驅動整個生态圈的優勝劣汰,進而不斷向更有競争力的方向進化。
我們DataWorks研發團隊也寄期望于在這套架構之上,實作彈内彈外的共赢模式的合作,推動雲智能事業群下的産品形成合力。
五、前後端組合拳
所謂架構,不僅是技術上的事情,同時也要對人力的配置設定組織提供整套的指導方案。在應用了微服務架構之後,DataWorks研發團隊的職責顯然不能僅僅局限于日常的需求開發,作為微服務架構的倡導者,在推進架構的同時我也對團隊的前後端職責進行了思考。首先前後端需要拉出一個架構小組,通過指導前端元件和後端微服務的設計來影響整個架構的進化,團隊内需要有關注面向領域設計的研讨,分析每個插件是否是領域性的,同時需要有把關的同學,稽核第二方(彈内非本團隊的開發者)和第三方(彈外的傳遞團隊或者來自客戶的行業開發者)送出的插件設計,防止不良應用破壞體系建構。
同時,微服務架構由于語言無關性,還抹平了一些技術上的鴻溝,前端同學很多擅長nodejs,也可以在微服務的設計中一展身手,更使前後端在技術上的交流和溝通會更加有默契。我們的産品線中還有一個特殊的産品:AppStudio,專職于WebIDE的研發工作,将來無論是資料服務提供的資料出口,還是FaaS裡的函數,還是微服務本身的開發,都可以與AppStudio結合,由使用者自主開發,可以完全不用脫離DataWorks全域大資料平台,就從資料開發到報表設計,再通過微服務編寫業務邏輯,達成資料輸出的目标,一站式完成使用者的訂制需求。
架構驅動職責的轉變
上圖是未來的團隊職責分工的一個構思,前後端研發同學在這套組織架構下,打出一套組合拳,直擊痛點問題,幫助使用者攻克技術難關,實作生态的繁榮昌盛。
六、展望未來
技術和架構的未來是什麼樣子的?在我的理想中,軟體工程的研發技術應該是一個沒有止境和邊界,且越來越智能化的領域。DataWorks的産品中已經有很多開始向智能化的方向前進,比如基于VSCode應用了Markov算法的智能程式設計插件。研發團隊的未來很大程度上取決于體系的架構,我們應該鼓勵創新,鼓勵對技術前沿和邊界的探索,不應該人為的制造太多規約進而限制了思考的天馬行空。如果有一天,智能化程式設計終于開始替代人工開發,那麼通過改變架構的設計,研發人員也一定可以在新的架構中尋找到新的職責。
世界是變化的,也是有規律的,我們的技術願景應當是為這個變化的世界建構出成熟且不斷進化的工程體系。面向未來,擁抱變化,為了無法計算的價值!
點選
連結,了解團隊資訊,加入飛天大資料交流群和DataWorks産品進行交流!