阿里玄難:面向不確定性的軟體設計幾點思考

阿里技術_發表於2018-12-11

640?wx_fmt=jpeg

阿里妹導讀:在紛繁複雜的業務發展中,變化已成為了唯一的不變。如何保障基礎設施的安全、高可用性,同時提供高效的創新支援?今天,阿里副總裁、業務平臺事業部掌門人玄難,結合阿里巴巴業務平臺建設和個人多年大型軟體設計經驗,提煉成幾點思考,希望對大家的軟體架構設計有所啟發。


640?wx_fmt=jpeg

 

玄難

阿里副總裁

業務平臺事業部掌門人

 

特別說明:本文中所說的軟體都指代面向終端使用者的偏業務的軟體,不包含作業系統、中介軟體等系統軟體。

 

1、軟體發展的幾個階段

 

  • 軟體工具和資訊化階段:軟體最早是為了數值計算,以工具的形態出現的。包括PC時代我們非常熟悉的Excel,Word這些好東西。以及典型的企業內部管理的資訊系統,例如:企業流程審批、進銷存管理系統等等。

  • 網際網路服務階段:隨著PC網際網路興起,淘寶、QQ、Google、新浪這些全新的網際網路服務逐步進入了我們的日常生活。

  • 社會基礎設施階段:隨著移動網際網路、IOT、人工智慧的出現和高速發展,各種各樣的軟體進入社會經濟生活的方方面面,軟體之間相互連線,構成了一個紛繁複雜的生態系統,變成了不可或缺的社會基礎設施。

 

隨著軟體形態的變化,過去非常高效的系統架構和組織形態遇到了全面的挑戰。因為我們所處的環境已經從量變到質變,突破臨界點,產生了本質的不同。

 

阿里巴巴就是這個過程中的典型代表。從過去單一的電商業務演變成了複雜的經濟體,沒有了確定性的業務邊界,蓬勃發展的業務不可預測。比較典型的特徵就是:


  1. 從過去的一個淘寶演變成了幾十個事業部和公司,新零售、雲端計算、文娛健康等等幾百種業務,還在不斷地快速演進;

  2. 從曾經的一個Denali系統,通過分散式架構演變成了上萬個系統的群落,各種業務邏輯交織在一起橫貫眾多系統,說不清道不明;

  3. 從曾經幾十個人的協同演變成了幾萬人的協同,每個人都像在原始熱帶雨林,不知業務全貌,盲人摸象;

  4. 從曾經的可停機發布演變成了不可中斷,連續進化的社會基礎設施,不僅要系統穩定性,更要業務連續性。如何確保這個基礎設施的安全、高可用性,同時提供給業務方高效無障礙的創新支援,就是我們必須去解決的核心問題。


針對這些問題,我們對軟體設計產生了幾點基本思考。

 

2、傳統軟體設計:外延的確定性

 

作為程式設計師,我們都知道:軟體要能符合預期,我們需要確定性。不確定性對程式設計來說是致命的。所以我們經常會聽到抱怨“需求又變了”,網上很多段子都是程式設計師討伐業務方和產品經理不停變更需求。

 

軟體在“工具和資訊化”時代,本質上是把原來的人工工作,用計算機軟體來模擬,實現電子化,因此有個典型的特徵:業務領域、軟體職責和功能邊界都相對清晰。因此最經典軟體工程理論是瀑布模型:收集需求、畫UserCase、確定功能集合、模型抽象、概要設計、詳細設計、編碼、單元測試、整合測試、使用者測試、上線執行。然後投入下一個版本的迭代。傳統的軟體開發大多數都是這種模式。這種模式特別強調文件質量和變更的全流程一致。

 

在網際網路服務時代,用計算機軟體實現了靠人肉無法完成的能力,為人類社會提供了很多全新的服務能力。我們繼承了傳統的軟體工程理論,也做了適度的改良。為了縮短版本迭代的時間,更快地驗證產品想法獲取使用者,大多數團隊採用敏捷模型。本質上是把需求批發模式變成了零售模式。這種模式最大的好處就是對產品需求的快速響應,但致命的是每次敏捷大多數情況下是在不斷地打補丁,軟體架構快速腐化。要不了兩年,敏捷事實上變成了蝸牛。再熬兩年,受不了了,就重構。但所謂的重構事實上是推倒重來。這種模式下幾乎沒有可用的文件了。

 

在前面這兩個階段的軟體設計理論都有一個基本假設:軟體邊界是確定的,我們通過歸納總結和適度的預測(避免過度設計)來進行模型抽象。通過模型抽象,我們設計了各種可配置性來快速接入需求,提升效率,也就是我們常說的產品化。通過介面設計和模組化設計來進行組織分工協作。通過系統架構的開放性來應對不能配置的變化。變化一般來自兩個方面:

 

首先是使用者量增長,通常是用分散式來解決,分散式資料庫,分散式快取、分散式服務,多機房多單元,CDN等等。在這方面阿里巴巴應該是做的非常優秀。從五彩石開始至今,阿里巴巴的架構基本上都是這一指導思想的落地實施和優化完善,也仍是應對使用者量快速增長的良方。

 

第二個方面業務功能的變化,我們通常說的系統可擴充套件性。通過傳統資料庫的大欄位或者NoSQL,用“後設資料+K-V儲存”的方式來應對資料資訊的不確定性;通過流程引擎來滿足工作流程的快速響應;通過規則引擎來代替程式中的大量If-Else,實現介面配置來實現規則的變化。通過UI元件化,配合UI的編輯器來快速調整使用者介面的變化。通過外掛技術來將容易變化,且相對複雜的邏輯從主流程中剝離出來進行擴充套件。我們去看目前比較的套裝優秀軟體都大致如此。

 

截止目前,我們的軟體研發,都是面向一個確定性的問題,類似一個圓圈,他是有需求邊界的,我們從四周向內聚,做抽象,就是我們的業務抽象或者建模;它就是我們的房子,被四個邊角承重牆劃清了邊界,裡面的裝修可以根據主人的愛好和階段性訴求重構,但沒法向外延展;它的特點是框架結構,業務領域模型抽象、元件化、版本化、外延向內;

 

3、思考角度的變化:核心的確定性

 

隨著移動網際網路,IOT,人工智慧的發展,軟體變成了社會的基礎設施,我們每個人被軟體牢牢地控制了,一天黏在手機和電腦上。人其實是作為終端接入軟體網路。社會形態是沒有邊界的,是連續變化的,不可預測的。阿里目前的業務也是沒有確定性邊界的,不知道明天會變成什麼樣,它不是版本化的,是在不斷在生長和變異。就沒有確定性的軟體外延。如果沒有確定性的外延,而軟體的執行又是需要確定性的,我們就只能去尋找確定性的核心。

 

如何理解這個變化。我們可以從機器學習的發展來類比。傳統的機器學習有很多的演算法模型,線性迴歸、決策樹、隨機森林演算法、邏輯迴歸、SVM、樸素貝葉斯、K最近鄰演算法、K均值演算法等等。我們要解決,首先要嘗試分析問題領域,才能選擇匹配的演算法模型,才能得到好的結果。如果是個非線性問題,但錯誤的選擇了線性模型,就拿不到結果。這種解決問題的思路,就是要先尋找一個確定性的問題邊界,才能向內尋找引數。但深度學習的解決思路有個本質變化,不定義問題域,只定義穩定的結構,BP神經網路,有輸入層,多個隱藏層和輸出層。如果我們把影像資料輸入進去,就構建影像分類和人臉識別的能力,語音輸入進去,就構建出語音識別的能力(當然沒有說的這麼簡單)。深度學習是由內而外的自我學習和生長的。

 

軟體工程也遇到同樣的問題,需要從外沿確定性轉變為核心確定性。從邏輯推理的角度來說,傳統軟體工程是以歸納法為主,區域性使用演繹法,而要面對外延不確定性的領域來看,需要找到穩定的核心基礎,然後以演繹法為主,區域性使用歸納法。我們先去尋找核心,核心向外生長和變異,原來的確定性是尋找外沿的確定,現在我們要尋找核心的確定。原來是歸納法,現在我們要演繹,找到不變的是什麼,就像人由基因控制的一樣。當然你也可以說這是一種跨業務領域的更高階的抽象。

 

640?wx_fmt=png

 

4、文件即程式碼

 

縱觀計算機發展歷史,軟體研發效率提升就是彌合現實世界和計算機二進位制世界的鴻溝。從二進位制編碼到彙編,到C語言,到物件導向的C++、JAVA。每一次升級都是用人類更容易理解的方式抽象描述現實世界,然後通過一個編譯程式無差異的翻譯成低階,直到計算機能直接執行的二進位制。每一次升級都帶來軟體研發效率的指數級提升,同時讓能參與軟體設計的人也是指數級增加,給整個社會帶來巨大的進步。這其中最大的功臣毫無疑問是編譯器。我們最核心的資產是編譯前的原始碼,而不是編譯後可執行的二進位制程式碼。因為我們編譯後的程式碼不容易理解,也不可能通過逆向工程還原出原始碼。丟掉了原始碼,基本上就失去了所有。

 

回到當下的業務領域,我們都聲稱自己是做業務的,例如業務平臺就聲稱支援了淘寶、天貓、拍賣、盒馬生鮮、天貓超市、飛豬機票、火車票等等上百種業務。但我們的程式碼中完全尋覓不到這些核心業務概念。我們都知道電商最核心的交易模式擔保交易、預售、團購、貨到付款等等也不可能在程式碼中找到。我們也沒有準確的文件來描述這些東西。這是傳統的軟體工程方法和技術侷限導致的。

 

我們所做的需求分析,概要設計,詳細設計到最後的Java程式碼,其實就是業務邏輯到計算機世界的一次編譯過程。這其中最大的問題就是人肉編譯,而不是機器無差別編譯,這個編譯過程因人而異。因為這種不確定性,導致所有的設計文件隨著時間的推移,與實際執行的程式碼之間產生不可彌合的鴻溝。一個業務系統的文件越來越沒有用處,也就越來越沒人寫了。如果不能實現文件即程式碼,我們就不能留下真實可用的文件。

 

我們需要把設計和實現融合在一起。我們看自然世界,所有的設計文件圖紙其實就是DNA,而DNA是在生命體的每一個細胞中都存在的。DNA的傳承就是生命的傳承。所有外化的文件最後都容易消失。就像秦始皇一把火就把人類多少年的沉澱和傳承毀掉了。但DNA裡面的生物的本能傳承是一代代的得到了傳承和優化。

 

目標:不存在獨立於可執行系統之外的文件。所有的資訊都蘊含在系統之中,只是通過一些工具進行視覺化,增強可讀性。所有的資訊都不能憑空存在,都必須屬於一個業務物件。

 

5、面向功能的元件化設計到面向業務的物件化設計

 

我們的世界可以按熵變化的方向,分為熵增的無機體和熵減的生命體。

 

無機體是靠設計、圖紙,自頂而下的層層分解細化設計,然後元件化拼裝出來的。典型特徵:標準元件化設計和批量生產來進行協同和提效。

 

生命體,是由內而外的生長和變異的。雖然看上去是元件化的,但因為基因不同,事實上不同生命體是不可替換,會產生排異反應的。所有組成部分是在基因的控制下同步生長的。生命體的生長和變異是連續的。

 

所有元件化構建出來的無機體,如果要有質變,都是推倒重來。就像我們的城市總在不斷拆遷中膨脹一樣。再如我們的7號樓,在設計結束,就決定了它只能是6樓,或許可以利用冗餘蓋到8樓,但如果增加到20樓,他一定會崩潰。要想蓋20層,只能推倒重來。

 

因此按抽象歸納,元件化設計的軟體系統,隨著業務發展,補丁越來越多,執行幾年就會被推倒重來是它的宿命。

 

有機體單個個體的複雜度也是有限的,是靠群體協作來形成巨大的規模和力量的。群體的進化是靠單體的變異和自然選擇來演進的,生命的進化是不可預測的,正如父親對兒子的成長和未來是不可預測的。

 

現在我們的業務系統都是由元件化系統,例如購物車、店鋪、詳情、庫存、交易、營銷、資金、支付、結算、財務體系構成。所有的業務實現,其實是資料在這些元件系統中流動來實現的。在這個執行系統中,我們看不到天貓、淘寶、盒馬、天貓超市、擔保交易、預售、團購這些我們耳聞目詳的東西。都體現在一個個分散的資料欄位和IfElse中。

 

我們的設計思路是,迴歸到業務本質,用物件化設計來讓業務可生長、繼承和變異。最基本的思路:整個系統的根基是業務。你將會看到一個實實在在的Class叫淘寶,天貓,他們有個父親叫市場,天貓超市是獨立存在的Class,它天貓的兒子。所有繼承了他們父親的基因,有獨立的品牌心智的業務都會在執行期真實的存在。通過物件來去除兄弟之間的相互影響。核心控制性基因是不可變的,但新能力的創造就脫離父親的影響能獨立發展,也可以創造出新的子業務。

 

同時我們還要建立一套業務物件協作機制,天貓和淘寶互相協同,大麥和飛豬是可以協同的,讓業務和業務之間產生連線,共同構成一個動態繁衍的生態體系。如果我們能把整個阿里巴巴商業體系圖示化出來,買家賣家進入淘寶天貓就會像接入遊戲,進入天貓超市就像真的進入一家超市,做拍賣真的要敲錘一樣,做出虛擬世界的真實感覺。

 

640?wx_fmt=png

 

阿里巴巴業務平臺的演進:以功能為中心以商業能力為中心以業務為中心,我們在路上。



640?wx_fmt=gif

你可能還喜歡

點選下方圖片即可閱讀


640?wx_fmt=jpeg

阿里玄難:藏經閣計劃首次在阿里應用落地


640?wx_fmt=jpeg

早訊 | 阿里已全面應用 IPv6;連任 Java 組織蓆位;全球數學大賽決賽開戰


640?wx_fmt=jpeg

首次公開!2018雙11技術數字全記錄


640?wx_fmt=jpeg


關注「阿里技術」

把握前沿技術脈搏

相關文章