
作者:ArweaveOasis,來源:PermaDAO
本文討論了採用微服務架構(或者說 Actor 模型)的優勢,分析了它為應用開發帶來的一定程度上合乎邏輯的複雜性。
@aoTheComputer 的發布無疑給整個 @ArweaveEco 生態乃至於整個 Web3 行業帶來了一種全新的思考與實踐。這不僅體現在廣大投資者的關注度上,更體現在吸引大量優質開發者開始深度研究之上。
是什麼阻礙了 Web3 的大規模採用?
很簡單,因為值得人們使用的去中心化應用太少了。
基於 Web3 基礎設施、開發工具、軟體工程實踐等方面的現狀,很多類型的去中心化應用當前幾乎是無法實現的。
在基礎設施方面,我認為 AO 的出現填補了其中一部分重大的空白。但是,目前構建大型去中心化應用的工程的複雜性,仍然是令人望而生畏的。這使得我們無法在資源受限的情況下——在事物發展的初始階段,通常如此——開發出更多樣化的、更大規模、往往也意味著更棒、功能更豐富的去中心化應用。
不要相信那些類似「智能合約/鏈上程序應該就是很簡單的,沒有必要搞得太複雜」之類倒果為因的鬼話!
現實問題並不是「不想」,而是「不能」——臣妾做不到啊。
AO 是運行在 Arweave 上的計算機系統,旨在實現可驗證的無限計算能力。它是 Actor Oriented(面向參與者)的簡稱。顧名思義,這說明運行在 AO 上的去中心化應用需要採用 Actor 模型為基礎的設計和編程方法。
事實上,AO 並不是最早將 Actor 模型用於區塊鏈(或者說「去中心化基礎設施」)的。比如,TON 的智能合約就是使用 Actor 模型構建的。說到 TON,我個人覺得它和 AO 在某些方面頗有相似之處。
對於尚未深入了解 Web3 的 Web2 開發者來說,想要迅速理解 AO 或 TON 相對其他「單體區塊鏈」的最大特色,一個方便的抓手是:把運行在它們之上的智能合約(鏈上程序)看作是「微服務」。而 AO 或 TON 是支持這些微服務運行的基礎設施,比如 Kafka、Kubernetes 等。
作為一個 20 多年來主要專注於應用開發的一名資深 CRUD boy, 我個人非常樂見 AO、TON 這樣的非單體區塊鏈的出現,並對它們的發展充滿期待。下面我想從一個應用開發者的視角,談談我對 AO 的看法,可能很多觀點還不太成熟。也許部分應用開發者會心有戚戚焉,那就足矣。
將 Actor 模型應用於區塊鏈,真的有必要嗎?
答案是肯定的。看看已經取得「大規模採用」的 Web2 應用,你就會明白。
太多的架構師已經知道如何將 Web2 應用「搞大」:微服務架構(MSA)、事件驅動的架構(EDA)、消息通信機制、最終一致性模型、分片……這些東西,不管叫什麼,總是與 Actor 模型共生共存的。其中的一些概念,甚至可以說只是一個事物的不同方面而已。所以在下面的行文中,我們不對「微服務」和 Actor 做區分,你可以認為它們就是同義詞。
今日網際網路的繁榮,離不開這些架構師的智慧。他們不斷地探索、實踐、總結,最終形成了一套完整的工程實踐體系。
作為 Web3 基礎設施,AO 做的很棒。至少,AO 作為(我眼中的)當前 Web3 領域的最佳去中心化消息代理,已經展現出巨大的潛力。我相信傳統 Web2 應用的開發者由此可以馬上理解其中的重大意義:倘若沒有 Kafka 或者類 Kafka 的消息代理可用,你能想像現在很多大型的網際網路應用「程序要怎麼寫」嗎?
雖然 Actor 模型在很多方面具有理論上的優勢,但是不管是 Actor 模型也好,微服務架構也好,在我看來,更多是開發者為了開發某些應用(特別是大型應用)所不得不承受之「痛」。
讓我們用一個簡單的例子來向非技術讀者說明這一點。假設世界上所有銀行都基於一個「世界計算機」來開展業務,而這個世界計算機是一個單體架構的系統。那麼,當工商銀行的客戶「張三」向在招商銀行開設帳戶的「李四」匯款 100 元的時候,開發者可以這樣編寫轉帳程序的代碼:
1. 開始一個事務(或者說「交易」,它們在英文中是同一個詞);
2. 在張三的帳戶上扣減 100 元;
3. 在李四的帳戶上增加 100 元;
4. 提交事務。
以上步驟不管哪一步出現問題,比如說第三步,在李四的帳戶上增加金額,因為某種原因失敗了,那麼整個操作都會被回滾,就像什麼都沒有發生過一樣。對了,程序這樣寫,我們稱之為採用「強一致性」模型。
倘若這個世界計算機是個採用微服務架構(MSA)的系統呢?
那麼,管理工商銀行帳戶的那個微服務(或者說 Actor)與管理招商銀行帳戶的那個微服務,幾乎不太可能是同一個。我們先假設它們確實不是同一個,前者我們稱為 Actor ICBC,後者我們稱為 Actor CMB。此時,開發者可能需要這樣編寫轉帳的代碼:
1. Actor ICBC 先記錄好以下信息:「張三向李四轉帳 100 元」;Actor ICBC 在張三的帳戶上扣減 100 元,並向 Actor CMB 發送一條消息:「張三向李四轉帳100 元」;
2. Actor CMB 收到消息,在李四的帳戶上增加 100 元,然後向 Actor ICBC 發送一條消息「李四已收到張三匯入的 100 元」;
3. Actor ICBC 收到消息,記錄好:「張三向李四轉帳 100 元,已成功」。
上面只是「一切都好」的過程。但是,如果某個步驟,比如說第二個步驟,「在李四的帳戶上增加 100 元」,出現了問題,怎麼辦?
開發者需要針對這個可能發生的問題,編寫這樣的處理邏輯:
-
Actor CMB 向 Actor ICBC 發送一條消息:「張三向李四轉帳 100 元,處理失敗」。
-
Actor ICBC 收到消息,在張三的帳戶上增加 100 元,並記錄:「張三向李四轉帳 100 元,已失敗」。
程序這樣寫,我們稱之為採用最終一致性模型。
以上,非技術讀者應該能直觀感受到開發單體架構的應用與開發 MSA 應用之間在工作量上的巨大差異了吧?要知道,上面所說的轉帳示例只是一個非常簡單的應用而已,如果我們把它稱之為應用,而不是功能的話。大型應用裡面的功能往往比這樣的例子要複雜的太多。
這個微服務應該多大?
換句話說,”這個微服務是不是太大了,應該一分為二?」
很不幸,這個問題沒有標準答案,它是一門藝術。微服務越小,就越容易通過創建新實例並按需移動它們來優化系統。但是,微服務越小,開發人員就越難實施複雜的流程,正如上面展示的那樣。
對了,將一個應用拆分為多個微服務,從資料庫設計角度看,即所謂的「分片(Sharding)」。微服務架構的最佳實踐之一,就是每個微服務僅使用一個屬於自己的本地資料庫。簡單來說,分片允許水平擴展。當數據集變得太大,無法通過傳統方式處理時,除了將它們拆分成更小的片段以外,別無他法(來進行擴展)。
回到微服務的拆分問題。為了更好的踐行這門藝術,我們需要掌握一些思維工具的使用。DDD(領域驅動設計)的 「聚合(Aggregate)」就是這樣一件你必須擁有的「大殺器」。我的意思是,它能幫助你摧毀軟體設計中的「核心複雜性」。
我認為聚合是 DDD 在戰術層面最為重要的一個概念。
什麼是聚合?聚合在對象之間,特別是實體與實體之間劃出邊界。一個聚合一定包含且僅包含一個聚合根實體,以及可能包含不定數量的聚合內部實體(或者叫非聚合根實體)。
我們可以使用聚合這一概念對應用所服務的領域進行分析和建模;然後在編碼的時候,就可以按照聚合來切分微服務。最簡單的做法,就是將每個聚合實現為一個微服務。
不過,即使你的手藝再嫻熟,這種事情你也不能保證第一次就做對。這個時候,一件讓你可以儘快對建模結果進行驗證、不行就推倒重來的工具,對你來說就彌足珍貴了。
還有什麼東西可能構成大型 Web2 應用遷移到 AO 生態的障礙?
我想談談語言和程序運行時的問題。
AO 是一個數據協議。你可以認為它是一套定義 AO 網絡中的各個「單元」如何實現協作的接口規範。目前,AO 的官方實現包含了一個基於 WASM 的虛擬機環境,以及一個編譯為 WASM 的 Lua 運行時環境(ao-lib),旨在簡化 AO 進程的開發。
Lua 是一種小而美的語言。一般認為,Lua 的優勢在於它的輕量級和易於嵌入其他語言,這使得它在特定場景(比如遊戲開發)中特別有用。但是,對於開發大型網際網路應用來說,Lua 語言並不是主流的選擇。大型的網際網路應用開發通常傾向於使用如 Java、C#、PHP、Python、JavaScript、Ruby 等語言,因為這些語言提供了更全面的生態系統和工具鏈,以及更廣泛的社區支持。
有人可能要爭論,這些語言都可以編譯成 WASM 字節碼,在 WASM 虛擬機裡運行。但是事實上,雖然 WASM 在 Web 前端開發領域的表現很強勢,但目前網際網路應用採用 WASM 作為後端的運行環境並不是一個主流選擇。注意,智能合約(鏈上程序)是 Web3 時代的「新後端」。
總結
綜上,我們已經討論了採用微服務架構(或者說 Actor 模型)的優勢,以及它為應用開發帶來的複雜性。有些複雜性是不可避免的。比如,即使在工程化更成熟的 Web2 環境中,基於消息通信來實現「最終一致性」對於許多開發者而言已經是不小的挑戰。在新生的 AO 平臺上開發 Dapp,這個挑戰似乎還要更加明顯——當然這是完全可以理解的。 以下連結文章的開篇就展示了一個例子。
https://github.com/dddappp/A-AO-Demo?tab=readme-ov-file#an-ao-dapp-development-demo-with-a-low-code-approach
我們都知道,公鏈之爭,其實是爭奪應用開發者的戰爭。那麼,在這種情況下 AO 要如何贏得開發者?
我認為需要繼續向已經獲得「大規模採用」的 Web2 學習。這不僅包括學習其基礎設施,還包括開發方法論、開發工具和軟體工程實踐等各個方面。在下一篇文章中,我會為大家展示我堅信的一種解決方案:低代碼開發。