Orleans 框架3.0 官方文檔中文版系列一 —— 概述

關於這個翻譯文檔的一些說明:

之前逛部落格園的時候,看見有個園友在自己的部落格上介紹Orleans. 覺得Orleans 是個好東西. 當時心想:如果後面有業務需要的時候可以用用Orleans框架.

當真的有業務需要的時候, 我驚奇的發現很多介紹Orleans框架的人,都只是寫了一個入門的示例. 關於Orleans框架的中文資料似乎很少.

直到翻到csdn部落格中有個叫閆輝的人有一個系列部落格叫《Orleans 2.0 官方文檔》, 我非常開心的點了進去,然後我就悲劇的發現這文檔幾乎是機器翻譯, 當然也不是沒有收穫. 受他的啟發,我決定自己來翻譯Orleans框架的文檔. 當然我的英文還停留在小學的水準, 因此我也是藉助機器翻譯.所不同的是我會盡量去理解文檔的內容, 在我理解的基礎上進行翻譯.以期能幫到需要了解Orleans框架的園友.

因此翻譯的準確度我理解的深淺直接掛鉤. 所以如果英文水準高的園友還請移步原版文檔( //dotnet.github.io/orleans/Documentation/index.html) 去看原版文檔. 翻譯有誤的地方也歡迎園友能夠指正,在此不勝感激.

 

概述

Orleans是一個跨平台框架,用於構建強大、可擴展的分散式應用程式.

Orleans基於 .NET 的開發人員工作效率,並將其引入分散式應用程式(如雲服務)的世界。奧爾良從單個本地伺服器擴展到雲中全球分散式、高可用的應用程式。

Orleans採用熟悉的概念,如對象、介面、async/awai和try/catch並擴展至多伺服器環境。因此,它可以幫助開發人員將單伺服器應用程式向構建彈性、可擴展雲服務和其他分散式應用程式擴展。因此,奧爾良通常被稱為”分散式 .NET”。

它由 Microsoft Research 創建,並引入了虛參與者(Virtual Actor)模型,作為為雲時代構建新一代分散式系統的新方法。Orleans的核心貢獻是其編程模型,它馴服了高度並行分散式系統原有的複雜性,同時也不要求開發人員有高超的開發能力.

 

Grains(顆粒)

所有通過Orleans建立的應用程式的基本單位都是Grains. 也可以理解為任何Orleans程式都是由一個一個的Grain組成的. Grain是一個由用戶自定義標識,行為和狀態組成的實體. 標識是用戶自定義的鍵(Key),其他應用程式或Grain通過鍵來調用該Grain. Grains是通過強類型介面(協議)與其他Grains或客戶端進行通訊. Graint是實現一個或多個這些介面的實例.

Grains 可以在任何存儲系統中存儲揮發性、持久性狀態, 因此,Grains隱式地對應用程式狀態進行分區,從而實現自動可伸縮性並簡化故障恢復。當Grains處於活動狀態時,Grains狀態保存在記憶體中,這樣可以降低延遲和數據存儲的負載.

Grains的實例化工作由Orleans runtime根據需要自動實現.一段時間不用的Grains將自動從記憶體中移除以釋放資源,這主要是因為Orleans框架允許通過唯一的標識去調用grains(不論這些Grains是否已經載入到記憶體中去); 同時支援故障自動恢復,因為調用方不需要知道Grains有沒有實例化,在哪個伺服器上實例化. Grains的生命周期由Orleans運行時進行管理——Orleans運行時負責激活/停用Grains,並會根據需要放置/定位Grains. 開發人員在調用它們的時候就好像它們在記憶體中一樣.

總之, Grains的標識穩定性,有狀態性,生命周期受Orleans運行時的管理性,使得基於Orleans框架開發的程式具有可伸縮性,可靠性以及較高性能,同時也不需要開發人員為了系統支援分散式而編寫複雜的程式碼.

 

示例:物聯網後台程式

    思考一下這樣一個物聯網系統的後台程式:程式允許設備接入,然後處理這些數據:過濾、聚合、匯總等;還要支援向設備發送命令. 在Orleans框架下,我們很自然的想到用Grains來對每個設備進行建模. 每一個Grain就像想對應的物理設備的一個雙胞胎兄弟一樣. Grains將設備最新的數據存放在記憶體中,以便更快速的查詢和處理這些數據,而不需要與物理設備進行直接通訊. 通過分析設備時序數據, Grains可以檢測設備的狀態或條件的變化(例如測量值超過某個閾值)來觸發某個特定的動作.

    下面是一個簡單恆溫器的建模:

public interface IThermostat : IGrainWithStringKey

{

    Task<List<Command>> OnUpdate(ThermostatStatus update);

}

    可以通過調用OnUpdate方法把前端的事件發送給相應的Grain, Grain再根據需要有選擇的把命令回饋給物理設備.

var thermostat = client.GetGrain<IThermostat>(id);

return await thermostat.OnUpdate(update);

    相同的Grain可以單獨實現一個介面,用於控制系統與之交互:

public interface IThermostatControl : IGrainWithStringKey

{

Task<ThermostatStatus> GetStatus();

Task UpdateConfiguration(ThermostatConfiguration config);

}

    這兩個介面(IthermostatIThermostatControl)由一個類來實現:

public
class
ThermostatGrain : Grain, IThermostat, IThermostatControl

{


private ThermostatStatus _status;


private List<Command> _commands;

 


public Task<List<Command>> OnUpdate(ThermostatStatus status)

{

_status = status;

var result = _commands;

_commands = new List<Command>();


return Task.FromResult(result);

}

 

public Task<ThermostatStatus> GetStatus() => Task.FromResult(_status);

 

public Task UpdateConfiguration(ThermostatConfiguration config)

{

_commands.Add(new ConfigUpdateCommand(config));


return Task.CompletedTask;

}

}

以上的Grain類不保存其狀態,後續的文檔中提供了更詳細的狀態持久化的示例.

 

Oreans運行時

    Oreans運行時實現了Oreans程式的編程模型. 運行時的主要組件是silo, silo負責託管Grain. 通常, 一組silo是以集群方式運行的, 並以此來實現可伸縮性和容錯性. 當這些silo作為集群方式運行的時候,silo之間彼此協調分配工作, 檢測故障以及故障恢復. Orleans運行時使得集群中的Grian能夠像在一個進程中一樣彼此相互通訊.

    除了核心編程模型之外,silo還為grains提供一組運行時服務,如計時器、提醒(持久計時器)、持久性、事務、流等. 相關的詳細資訊, 請參閱下面功能部分.

    Web以及其他外部客戶端通過客戶端類庫調用集群中的Grains,客戶端類庫將自動管理網路通訊. 當然還有更簡單的方式: 客戶端與Silo託管到共同的進程中去.

    Orleans 兼容 .NET Standard 2.0 及以上版本. 能夠在裝有.NET Framework(只支援windows) 或.NET Core 的 Windows、Linux 和 macOS上運行.

功能

持久化

    Orleans 提供了一個簡單的持久化模型, 該模型可以確保處理請求之前Grain是可用 狀態的, 並保持一致性. Grain 可以有多個命名持久化數據對象. 例如:把用戶配置命名為”Profile”;把庫存命名為”Inventory”來做持久化. 而這些持久化對象可以保存在任何的存儲系統中. 例如:把用戶配置(Profile)保存到資料庫A, 而庫存(Inventory)則保存到數據B. 當Grain運行時,Profile和Invertory都將被載入到記憶體中去, 這樣,在處理里讀取請求的時候就不用再去訪問存儲器. 當Grain的狀態被更新時,調用 state.WriteStateAsync() 就可以確保狀態的持久性和一致性. 更多詳細資訊,請參閱Grain持久化的相關文檔.

分散式ACID事物

    除了上述簡單的持久化模型外,Grain還支援有狀態事務: 可以把多個Grain放到同一個ACID事務中去,無論這些Grain的狀態存儲在哪裡. Orleans的事務是分散的分散式事務(沒有中央事務管理器或事物協調器),並且支援序列化隔離. 更多Orleans 事務的詳細資訊, 請參閱後續文檔和微軟Resarch技術報告( //www.microsoft.com/en-us/research/publication/transactions-distributed-actors-cloud-2/).


    流(或者說流計算)可以幫助開發者近乎實時地去處理連續數據. 流是託管在Orleans框架中的: Grain或客戶端發布或訂閱流之前,無需創建或註冊. 這樣使得流的產生者、消費者、基礎框架相互之間進行極大險度的解耦. 流處理的可靠性: Grains可以存儲檢查點(游標). 並可以在激活期間或者之後的任何時間重置已存在的檢查點. 流支援向消費者傳輸批量消息,並以此提高傳輸效率和恢復性能. 流由排隊服務(如:Azure事件匯流排、Amazon Kinesis等)提供支援, 任意多個流可以多路復用到較少的隊列上,並在整個集群中均衡的處理這些數據.

Timers & Reminders(此處本來想翻譯提醒的,但感覺怪怪的,索性就不翻譯了)

Reminders 和Timer都是Grain的一種調度機制. Reminder主要用於在未來的某個時間點(就算Grain當時沒有激活)完成指定的操作(針對Grain被持久化到存儲器的情況); 而Timer則是用於處理非可靠的頻繁出現的事件(例如某些不重要的通知). 更多Timer 和 Reminders 請參閱後續文檔.

靈活的Grain放置

    當Orleans激活一個Grain時,Orleans運行時決定在哪個伺服器(silo)上進行激活, 這個過程被成為Grain放置. Orleans的放置過程是完全可以靈活配置的, 開發人員可以從一組開箱即用的放置策略中進行選擇,可選的選項有:隨機,本地優先,基於負載以及自定義邏輯. 這使得Grain的放置非常具有靈活性, 例如: 可以將Grain 放置在靠近需要操作的資源上或者跟它有通訊往來的其他Grain伺服器上.

Grain 版本控制和異構集群

    應用程式的程式碼都會隨著時間或者業務的發展而變化, 如何將這些變化安全快捷地升級到生產系統(這裡應該是不停機更新)會面臨很大的挑戰, 特別是在有狀態的系統中. Grain 介面支援版本控制. 集群中維護了一個映射表, 分別記錄了在集群中有哪些Grain 可以被哪些Silo所使用, 以及實現的版本. Orleans運行時會結合這個記錄資訊與Grain放置策略配合使用,以便客戶端調用的時候Orleans運行時決定路由到相對應的Grain上. Orleans除了支援Grain版本控制外,還支援異構集群. 不同的Silo可以有不同Grain實現集. 更多相關資訊,請參閱 Grain版本控制相關文檔.

可伸縮性&容錯性

    Orleans在設計的時候,就已經充分考慮了系統的可伸縮性. 當有一個新的Silo加入到集群時,Orleans會根據需要去激活它; 當某個Silo由於某個原因(系統規模縮減或節點故障)需要從集群移除的時候,在當前Silo上的Grain會集群的其他Silo上面重新激活. Orleans集群,最小可以縮小到單Silo服務. Orleans支援可伸縮性的同時也支援容錯性: Orleans集群會自動檢測各個Silo是否故障,並能快速地從故障恢復.

處處運行

    Orleans可以運行在任何支援.net core 或 .net Framework的系統上,包括Windows,Linux,macOS,並支援通過K8s部署到docker 等其他物理或虛擬主機上,以及像Azure一樣的共有雲上的Paas服務.

無狀態工作者

Grain可以通過添加一個特殊的標記,使它與其它Grain之間沒有任何關聯狀態. 這樣就可以在多個Silo上同時激活, 從而增加無狀態操作的並行性. 有關更多資訊,請參考無狀態工作者Grain的相關文檔.

Grain調用過濾器

    Grain調用過濾器是指多個Grain之間的公共邏輯. Orleans支援傳入和傳出調用過濾器. 常見的過濾器用例有: 授權,日誌,遙測以及錯誤處理等.

請求上下文(Request Context)

元數據和其他資訊可以使用請求上下文(Request Context)在一些列的請求中傳遞. 請求上下文(Request Context)可以用來保存分散式跟蹤資訊或其它用戶自定義的值.

開始

    請參考入門教程.

編譯生成

在Windows系統可以通過運行 build.cmd 腳本在本地生成Nuge包,然後從”/Artifacts/Release/”目錄引用所需的Nuget包。接下來就可以運行 test.cmd腳本進行版本驗證測試,以及運行 testall.cmd 較本進行功能測試。

在Linux或Mac系統則通過運行 build.sh腳本 或 運行命令 dotnet build ./OrleansCrossPlatform.sln 來生成Orleans。

官方編譯

    最新的穩定的發布在此處

    夜間生成(即每天晚上進行生成)發布到 //dotnet.myget.org/gallery/orleans-ci 這些生成通過了所有的功能測試,但是沒有像發布穩定版本或預發布版本那樣進行徹底測試。

在項目中使用夜間生成的Nuget包

    若要在項目中使用夜間生成,請使用以下任一方法添加 MyGet 源:

    修改 .csproj 文件,在項目文件添加以下節點

    <RestoreSources>

        $(RestoreSources);

        //dotnet.myget.org/F/orleans-ci/api/v3/index.json;

    </RestoreSources>

    或者

    在解決方案目錄下面,創建一個Nuget.Config文件,並添加以下內容

    <?xml version="1.0" encoding="utf-8"?>
										

    <configuration>

        <packageSources>

        <clear />

        <add
key=“orleans-ci”
value=“//dotnet.myget.org/F/orleans-ci/api/v3/index.json” />

        <add
key=“nuget”
value=“//api.nuget.org/v3/index.json” />

        </packageSources>

    </configuration>

社區

  • 在GitHub 的 issue Stack Overflow 提題
  • Gitter 聊天室
  • Orleans 部落格
  • 在Twwitter 上關注Orleans 賬戶 @msftorleans (沒有微博帳號,哈哈哈)
  • OrleansContrib – 給Orleans設計各種插件的社區項目。 包含 健康,設計模式,存儲提供程式等。
  • 為希望改進Orleans而貢獻程式碼的開發人員提供的指南
  • 我們還鼓勵您通過GitHub來報告bug 或者在GitHub啟動一個新的技術討論.

授權

這個項目的授權協議是 MIT license.

快捷鏈接

Orleans 的起源

Orleans是在微軟研究部創建的,設計用於雲中。自 2011 年以來,它已被多個 Microsoft 產品組廣泛用於雲和內部辦公,其中最引人注目的是遊戲工作室,如 343 工業公司和聯盟,作為Halo 4和5、Gears of War 4背後的雲服務平台。

2015年1月開源以來吸引了許多開發者,他們形成了.NET生態系統中最具活力的開源社區之一。在社區開發人員和微軟Orleans團隊的積極合作中,每天都會添加和改進特性。微軟研究院繼續與Orleans團隊合作,推出新的主要功能,如地理分布、索引和分散式事務,這些功能正在推動最新技術的發展。對於許多.NET開發人員來說,Orleans已經成為構建分散式系統和雲服務的首選框架。