新一代架構模式 water:超越 Serverless 的雲研發架構模式

雲研發架構模式

機緣巧合之下,我看了解到了騰訊新出的 Nocalhost 工具 —— 一個雲原生的雲開發環境工具。就我的而言,看到這個工具的第一眼我是很是興奮的。終於,個人雲研發理論體系(《雲研發:研發即代碼》)又迎來一個歷史時刻。前端

簡單來講,Nocalhost 只是作了一件簡單的事情,把本地的開發環境放在了雲端。可是呢,結合最近很是火熱的無代碼/低代碼開發,又或者是各種的代碼生成,以及我和同事正在設計的 Datum 語言(原 Charj),頓時間我領悟到了一種新的、將來的、下一代的架構模式。儘管,理論體系還不是很是完善,可是我暫時稱之爲 Water。緣由是形將不重要,代碼再也不須要形了。git

Water 編碼架構,即人類編程的產出再也不是編程語言這一類型的字符串,編程時只是這種架構模式在 UI 上的呈現,其最終的存儲的形式則是:一系列的代碼的中間形式,如 AST、HIR、MIR 等。而代碼再也不被操做系統及文件系統束縛,它們能夠交由更小粒度的架構因素控制,即函數。代碼再也不須要以文件的方式存儲,系統的架構再也不是按目錄劃分的分層架構。程序員

太長不讀版github

Architecture

實時開發環境:即開發環境由 AST 呈現的編輯器/IDE + 瀏覽器組成。算法

  • 語言無關編輯器:
    • 呈現。接收通用 AST,以編程語言的方式重現代碼
    • 交互編輯。與人類進行交互
    • 語言無關。以任意語言展現和編輯
  • 瀏覽器

數據傳輸:二進制中間 AST數據庫

雲環境:由雲原生 Dev 雲 + 架構引擎 + 語言數據庫組成。編程

  • 架構引擎:
    • 操做系統無關。脫離操做系統的文件和文件夾進行架構規劃
    • 自動化架構。自動語義規劃架構
    • 類-圖數據庫展現(TBC)。
  • 編程語言數據庫(TBD)
  • 雲原生 Dev 雲:
    • Dev Online。雲原生的本地開發環境,即開發即部署後端

    • Prod Readly。隨時可部署 + 上線瀏覽器

引子 1:無代碼與雲研發

代碼的複雜度,同力同樣不會消失,也不會憑空產生,它老是從一種形式轉爲另外一種形式。服務器

2019 年,由於中臺的火爆 + Serverless 的崛起,我寫了一篇很長的文章在介紹如何設計《無代碼編程》。在這兩年的時光裏,出現了愈來愈多的所謂的『低代碼平臺』,可是它們並不是是我所想的類型,缺乏關鍵性的 DSL 抽象。不過呢,無代碼系統架構的設計和本文的主題並無太大的關係。可是呢,它們掀起了開發人員對於雲端開發的浪潮。

  • 雲設計。如 BeeArt 將大量的設計工做搬到了雲端來完成。
  • 雲 IDE。如 VSCode Remote、Eclipse Theia,它們能夠將新的應用部署到遠程開發。
  • 雲開發環境。如 Nocalhost,它們能夠解決存量系統的雲端開發問題。
  • ……

不過,這裏咱們要舉一個反面例子:『雲主機』,這中遠程開發模式可不是雲研發。從本地 IDE 到雲 IDE,本地設計軟件上雲等等的一系列效率工具的雲遷移,它將使得咱們在將來在雲上(瀏覽器端)完成整個研發。而對於咱們這些開發人員來講,重要的不是結果,而是如何去實現這樣一個架構。

引子 2:代碼架構與操做系統

分層架構就是建文件夾。

接着,咱們來講一些更有意思的事情,代碼存在的形式。在現今的軟件開發中,咱們以目錄做爲邊界來設計分層架構,以文件做爲代碼的載體。而這種形式存在的一個主要緣由是,咱們開發時依賴於操做系統的存儲:文件系統。對於文件系統而言,文件和樹形目錄的抽象邏輯概念即是人類所能接受的概念。

分層架構 vs 模塊 vs 包

若是你熟悉 Java 語言的話,你會發現操做系統限制了 Java 語言的軟件架構。一個主要的特徵就是包,即目錄便是包,com.phodal.water 對應了 com/phodal/water。而到了今天咱們習慣了使用目錄這種機制來進行包管理。如在最近幾年開始流行開來的整潔架構,它是一種圓環型(or 洋蔥式)架構,它就受限於目錄的影響,使得系統最後的實現並非那麼直觀。

(ps:因爲篇幅所限,這裏就不展現做更詳細的介紹了。)

若是你對於整潔架構又或者是分層架構不是很是瞭解,那麼你能夠參考我以前相關的文章和開源項目:

文件 vs 類

在 Unix/Linux 系統中,一切皆文件。

對於編程語言來講,咱們經常使用的好習慣是:一個類只在一個文件裏。儘管對於 Java 之外的語言來講,並不是如此,可是這樣實現易讀、易維護。與此同時,咱們也習慣於將類似的行爲構建在同一個類中,即富血模型。所以,在那本開源電子書《系統重構與遷移指南》,我一直在說服人們這樣去作。

過去,咱們一直侷限於文件的規則。因此,讓咱們考慮一下問題,若是咱們能夠脫離操做系統呢?若是說,咱們不帶用文件來約束類,那麼就不須要這一類規則。

引子 3:代碼的中間表示

爲了實現上面的一系列概念,咱們須要從新設計整個系統,其中的一個關鍵部分就是:代碼的中間表示。若是你熟悉編譯原理的話,也就懂了,只有給人的時候,纔會以編程語言的形式出現。

開發態

對於咱們來講,只要咱們看到的是易於閱讀的代碼,它是中文的、英文的,又或者是甲骨文都不重要。反正,咱們寫的代碼是給本身看的,這些字符最後會通過層層轉換爲特殊的格式。

而在 IDE 與編輯器裏,爲了實現對於編程語言的高亮、智能感知等的支持,須要從新實現語言的類 AST 解析。如 VSCode 裏的 LSP,Intellij IDEA 中的 PSI,Textmate/VSCode 中的 textmate 高亮語法等等。

因此,讓咱們思考一個問題,若是咱們是以類 AST 的形式存儲的話,那麼咱們就不須要實現這一類解析。它們只須要在展現的時候,將其轉換爲人類所熟悉的編程語言便可。

編譯態/運行態

在和同事一塊兒設計 Datum(原 Charj,改名爲 Datum)語言的半年期間,我分析了市面上主流的一些語言的中間表示,如 Python 和 JVM 的 bytecode,Rust 的 MIR 等等。它們就是各類中間表示,可是相差並非很是多,原理也是相似的。它們都是由上一步的 AST 轉換而來的,以接近底層的方式從新設計。

這一個時候,還引起了一個更有意思的問題:若是某部分代碼沒有變動的話,那麼我須要從新編譯嗎?既然某一個特定的部分沒有辦法,那麼它就不會發生改變。

與此同時,一個更有意思的事情是,全部的修改只須要打個 patch 便可,應用再從新運行。

新代碼架構:water

編程語言是寫給人看的代碼,寫給機器運行的機器碼。

基於上述的思想,咱們能夠設計新一代的代碼架構:water。由於代碼的形態已經再也不重要了,用什麼語言寫也再也不重要了,只須要一個統一的後端(編譯器後端)便可。讓咱們先給出第一個版本的架構定義:

Water 編碼架構,即人類編程的產出再也不是編程語言這一類型的字符串,編程時只是這種架構模式在 UI 上的呈現,其最終的存儲的形式則是:一系列的代碼的中間形式,如 AST、HIR、MIR 等。而代碼再也不被操做系統及文件系統束縛,它們能夠交由更小粒度的架構因素控制,即函數。代碼再也不須要以文件的方式存儲,系統的架構再也不是按目錄劃分的分層架構。

從上述的定義來看,它具有如下的特性:

語言無關。由於存儲的形態是 AST 形式的 DSL,因此開發人員能夠用任意的語言開發。如 A 使用 Java 語言開發,B 使用 JavaScript 語言開發,它們在存儲時將能夠轉換爲統一的 AST。而 B 程序員在本身的編輯器上使用的是呈現語言,因此 B 看到的 A 寫的代碼能夠是 JavaScript,而再也不須要是 Java 語言。再理於 Java 程序員 A,A 使用的是 Java,它能夠選擇的呈現語言是 Java,因此哪怕一個 C 程序員選了 Golang,它也將看到的是 Java 的呈現。(PS:固然了,這只是理論上,還有諸多的問題有待解決。)

細粒度權限管理。現今的代碼管理機制之下,對於開發者權限的管理是以代碼庫爲單位的。可是在新的架構模式之下,它能夠控制到函數的級別。主要是因爲代碼已經變爲了數據,開發人員只編寫模型和行爲。它還能實現再更細的粒度上,結合我司大佬提出的 Typeflow 的思想,就能夠控制到函數的粒度進行權限管理。即特定的開發人員,只擁有修改某一特定業務代碼集權限。

自動化架構。經典的架構機制依賴於文件夾的定義,類似行爲和功能的代碼以文件夾(也稱之爲包)的形式統一。而當咱們消除了架構中文件和文件夾的概念以後,每一個模型及其行爲以新的形式存在。試想一下在圖數據庫中,咱們如何去表示數據及其關係,那麼它就能夠不斷自動地優化架構,如基於聚類算法實現自動包定義。

一切皆數據。在 Unix/Linux 系統中,一切都是文件。而到了雲時,一切都是數據。儘管,從某種意義上來講,文件也是數據的一種。代碼自己也是數據。

其它一些有意思的內容:

語言數據庫。當咱們把編程語言轉換爲數據以後,咱們面臨地挑戰有兩個:數據的形式以及如何存儲?即便在 5G 的場景之下,咱們也須要考慮一下 4G 網絡傳輸的問題,那麼傳輸的介質多是某種二進制形式的包,如 Android 裏的 dex 包的形式,並帶有其它豐富的信息。

編輯態優先。脫離了語言的限制以後,這種架構模式之下,咱們還要考慮的一大因素是:編輯器/IDE 上的呈現與交互。咱們須要實現快速其的編輯與反饋,所以編輯態優先。

還有其它一些有意思東西,咱們能夠想象一下。

超越 Serverless

因而乎,咱們能聯想到另一個有意思的概念是 Serverless。

Serverless 架構是指大量依賴第三方服務(也叫作後端即服務,即「BaaS」)或暫存容器中運行的自定義代碼(函數即服務,即「FaaS」)的應用程序,函數是無服務器架構中抽象語言運行時的最小單位。在這種架構中,咱們並不看重運行一個函數須要多少 CPU 或 RAM 或任何其餘資源,而是更看重運行函數所需的時間,咱們也只爲這些函數的運行時間付費。 —— 《Serverless 架構應用開發指南》

而咱們整個新架構的部署模式與 Serverless 是很是相近的,而咱們系統仍是一個完整的總體,能夠不依賴於大量的線上服務。因爲編譯與開發一體,咱們完成開發的同時,便完成了部署。從某種意義上來講,water 架構會比 Serverless 更快,還更適合於複雜架構應用。

PS:我將會用一篇新的文章來介紹這種模式。

模型-行爲-分離

行爲是圍繞模型而構建的,在整個的機制之下,代碼已經再也不受模型的限制。接着,咱們要解決的老是就是數據庫的問題。

現今,咱們的編程語言受限於模型,而模型受數據庫影響。在這個狀況下,若是咱們不依賴於模型,那麼咱們須要設計一種新的機制,以讓咱們脫離數據庫的束縛 —— 那大概只能發明一種新的數據庫了。

回過頭來看,數據庫自己也是一種數據。那麼,從現有的論文裏去尋找一種更好的數據模式,也就變成了一件很是有意思的事。

其它

關於這個新的架構模式,我還在研究和思考中,將來依舊有很大的不肯定性。可是,它真的很是好玩。

也歡迎到 GitHub 討論和研究:github.com/phodal/wate…

相關文章:

相關文章
相關標籤/搜索