微吼云上線多路互動直播服務 加速多場景互動直播落地
844
2025-03-31
本文翻譯自https://doc.akka.io/docs/akka/current/guide/actors-intro.html
Actor模型如何滿足現代分布式系統的需求
正如前面主題敘述的一樣,常見的編程實踐沒有很好的解決高要求的現代系統的需求。幸好,我們不需要廢棄已有的編程實踐。相反,Actor模型以一種原則性的方式解決了這些不足之處,使系統更加匹配我們的預期模型。Actor模型抽象使你以通信的方式思考你的代碼,像一個大組織里人與人之間的交流一樣。
Actors使我們:
無需借助鎖實現封裝。
使用響應信號、改變狀態和相互發送信號的協作實體的模型驅動整個應用向前。
不再擔心和我們的世界觀不匹配的執行機制。
相對于調用方法,actors之間發送消息。發送一條消息并未將“執行線程”從發送者轉移到目標。一個actor可以發送一條消息并無阻塞的繼續運行。因此,在同樣的時間內,它可以完成更多任務。
對于對象,當方法返回時,它會釋放對其執行線程的控制。在這方面,actors和對象非常像,處理完當前消息后它們回復該消息并返回執行。這樣,actors實際上實現了我們對“對象”設想的執行:
消息傳遞和方法調用之間一個重要的區別是消息沒有返回值。通過發送一條消息,一個actor委派一個任務給另一個actor。正如我們在上篇《一個調用棧的錯覺》部分所看到的,如果發送消息的actor希望得到一個返回值,那么它要么需要阻塞要么在同一個線程內執行另一個actor的任務。相反,接收消息的actor在一個回復消息中傳遞結果。
我們的模型需要的第二個關鍵改變是恢復封裝。Actors像對象響應方法調用一樣響應消息。區別在于不是多線程入侵了actor并對內部狀態和不變體造成破壞,而是actors獨立處理收到的消息,并且它們一個一個地響應連續到來的消息。雖然每個actor連續地處理發給它的消息,不同的actors之間并發地工作,所以一個actor系統可以同時處理硬件可支持數量的消息。
因為每個actor中最多一個消息正在被處理,一個actor無需同步即可保持不變體。這無需使用鎖而自然存在:
總之,當一個Actor收到一條消息時:
Actor將這條消息添加到隊列尾部
如果Actor沒有被調度執行,它將被標記為ready。
一個(隱藏的)調度器實體獲取這個Actor并開始執行它。
Actor在隊列頭部取出一條消息。
Actor改變內部狀態,給相應actor發送消息。
Actor被調度完畢。
為了完成以上行為,每個Actor有:
一個郵箱 (存儲收到消息的隊列)
一個行為(actor的狀態,內部變量等等)
消息 (代表一個信號的數據段,類似于方法調用及參數)
一個執行環境 (響應消息的actors所處的并調用actors的消息處理代碼的機器)
一個地址 (more on this later)
消息存到actor的郵箱。Actor的行為描述actor如何響應消息 (比如發送更多的消息和改變狀態)。一個執行環境管理一個線程池以透明地驅動這些行為。
這是一個非常簡單的模型,并且它解決了上篇文章枚舉的問題:
通過將執行與信號解耦保持封裝 (方法調用轉移執行,消息傳遞沒有轉移)
不再需要鎖。一個actor的內部狀態只有通過一個一個被處理的消息修改,這消除了當試圖保持不變體時的競爭。沒有了鎖,發送消息的actors不會被阻塞。成千上萬的actors可以被高效的調度在十幾個線程上以發揮現代CPUs的最大潛力。任務委派是actors操作的自然模式。
Actors的狀態是本地的并且沒有被共享,修改和數據通過消息傳送,這映射了現代內存層次結構的真實工作方式。在許多情況下,這意味著只轉移包含消息中數據的cache行而將局部狀態和數據cache保持在原本的核。這個模型恰好映射了遠程通信——狀態被保存在機器RAM內,修改和數據作為數據包(packets)通過網絡傳送。
因為沒有了相互發送消息的actors之間共享的調用棧,所以我們要以不同的方式處理error情況。有兩種我們需要考慮的errors:
第一種情況是當目標actor被委派的任務由于任務出錯而失敗時 (典型的是校驗問題,比如一個不存在的用戶ID)。這種情況下,目標actor封裝的服務是完好無損的,只是任務自身是錯誤的。目標actor應該回復消息發送者actor復一條消息,報告錯誤情況。這沒什么特別的,錯誤是域的一部分,因此是普通信息。
第二種情況是當一個服務自身遇到一個內部錯誤。Akka將所有actors組織成一個樹狀層級結構,例如,一個actor是它所創建的新actor的父親。這和操作系統將進程組織成一棵樹十分相似。就像一個進程一樣,當一個actor失敗的時候,它的父actor被通知并且它可以對失敗做出反應。同樣地,如果父actor停止了,它的所有子actors也遞歸地停止。這個服務被稱為監督,它是Akka的核心。
一個監督者(parent)可以決定在特定類型失敗的時候重啟或者在其他類型失敗的時候完全停止它的子actors。子actors不會悄悄地死掉 (帶有進入一個無限循環的明顯異常),相反它們要么失敗,它的父actor處理error,要么停止 (這種情況下相關的單元自動被通知)??傆幸粋€負責管理一個actor的實體:它的父actor。重啟在外部不可見:當目標actor重啟之后,相關的actors可以繼續發送消息。
現在,讓我們簡單看一下Akka提供的功能。
智能數據 EI企業智能 表格存儲服務 CloudTable
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。