作者: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 學習。這不僅包括學習其基礎設施,還包括開發方法論、開發工具和軟體工程實踐等各個方面。在下一篇文章中,我會為大家展示我堅信的解決方案:低程式碼開發。