Orleans分布式框架-1
一、痛點
傳統應用常用的三層結構通常為:Web層-服務層-數據層(RDBMS或No-Sql),隨着業務發展,數據庫層通常會存在瓶頸,為了緩解數據庫的壓力,首先會在數據層上加一層緩存層,但緩存層對於海量數據輸入的幫助不大。
隨着業務繼續發展,高並發、大數據量應用場景就凸顯出來,如果繼續在單體應用上進行擴展,能做的就是增加消息隊列、異步、讀寫分離等,但優化空間不大,應用復雜度卻迅速增加,對於應用維護也是潛在的定時炸彈。
另一個解決辦法是既然單機部署不能滿足需求,可以做成集群。通過對單體營養按照分層結構進行縱向分離,將數據庫從應用服務器分離,將緩存從應用服務器分離,對分離的各個部分分別部署,再借助負載均衡完成集群效應。
補充:負載均衡
有若干種做法:
1、http重定向,用戶發起的請求會傳遞至重定向服務器,重定向服務器根據一定的算法得到服務器集群一個真實服務器的地址,然后返回給用戶,用戶再和這個真是服務器聯系。
2、dns解析,類似於http重定向,每次通過域名(www.google.com)訪問網站時,通過dns得到服務器地址,此時可以在dns服務器上設置一定的算法,每次得到不同的ip地址返回給用戶,用戶再訪問,實現負載均衡。
以上2種需要用戶發起2次請求。
3、反向代理,vpn被稱為正向代理,用戶把請求交給代理服務器,代理服務器訪問網站得到數據,之后代理服務器將數據返回個用戶。應用服務器不知道用戶的存在,只知道代理瀏覽器的訪問。
反向單例是在服務端的代理,代理服務器接收用戶的請求,再轉發請求給真實服務器,之后再返回給代理服務器再給用戶,這個過程中,用戶不知道真實服務器的存在。Nginx就是反向代理服務
還有其他類型的負載均衡。
orleans模型本身也是一種負載均衡。
回到分布式上,雖然通過負載均衡和集群可以撐下去,但細分到業務上看,對一個復雜應用來說,通常的性能瓶頸就是幾個核心服務,如果能對存在性能瓶頸的服務進行伸縮,就可以大大提高應用的整體可用性,又能提高資源的利用率,就是服務拆分。
服務拆分的一個結果就是雲生應用。
雲生應用最大的特點就是:
1、並行:同一時刻能夠處理多個任務。雲生應用本身就是以多個服務形式提供服務,自然是並行的。
2、分布式:一個應用/服務多次部署,以應對高並發,提升應用/服務的整體性能。
雲生應用雖然進一步拆分了有性能瓶頸的業務,通過服務拆分支持了並行,但實現的技術復雜度卻提高了。
二、解決思路
如何進行服務拆分,才能確保其能分布式部署,或是水平伸縮
把應用/服務設計成無狀態的。
OOP本身是對現實事物的抽象和封裝,但封裝出來的對象本身是沒有生命力的,只有在程序運行中對類進行實例化得到一個對象的實例時,才可以說這個實例對象是有狀態和行為的,因為這個狀態和行為是獨有的。
如果一個對象的狀態屬性是長期性的,那么就可以說這個對象是有狀態的。
對於應用來說,當運用運行時持有的數據能夠持久化,就稱其為有狀態的。
三、Actor模型
解決高並發的難點在於:
1、高性能
2、數據一致性問題
解決高性能可以通過水平擴展服務化解,解決第二個問題,就是鎖,但分布式場景下,鎖會大大降低應用的整體性能。
如果要兼顧性能,又確保數據一致性,就借助Actor模型。
Actor=狀態+行為+消息
一個應用/服務由多個Actor組成,每個Actor都是一個獨立的運行單元,擁有隔離的運行空間,在隔離的控件內,有獨立的狀態和行為,不被外界干擾,Actor之間通過消息進行交互,而同一時刻,每個Actor都只能被單個線程執行,就有效避免了數據共享和並發問題,又確保了應用的伸縮性。
Actor還基於時間驅動模型進行異步通信,性能良好,位置透明。
Actor模型賦予了應用/服務生命力(有狀態)、高並發的處理能力和彈性伸縮能力。
四、Orleans
orleans的高開發效率在於:
1、面向對象的編程范式去實現Grain
2、Grain透明實例化:應用無需關心Actor實例的創建、銷毀,可以直接調用Actor提供的方法。Actor的聲明周期由Virtual Actor運行時進行管理,類似GC,Actor類似於托管狀態。
3、Grain位置透明:Actor之間通過邏輯引用(非實例引用)互相調用,而不需要知道Actor所處的實際位置。
4、Grain單線程執行
5、Grain狀態透明存儲
6、異常的自動傳播
透明可伸縮體現在:
1、應用狀態的隱式細粒度划分
2、自適應的資源管理:Grain生命周期由Orleans托管
3、多路通信:Grain位置透明,Grain之間通過一組固定的TCP鏈接進行多路復用來進行消息傳遞
4、高效調度
5、顯式異步
Orleans所使用的的Actor模型(Virtual Actor模型)具有處理高並發和數據一致性的優勢,它能夠確保每個Grain都是獨立運行(單線程)和可尋址的,也能夠根據業務量,動態的增加Grain服務或銷毀不必要的Grain服務,達到高性能的目的。
五、Orleans的核心角色
1、Grain
Grain是一個可尋址的隔離的.NET對象實例(可尋址並非是new一個對象的內存引用,因為面向集群的任一機器,簡單的內存尋址是無法跨機器尋址的,實際上是通過Grain Identity實現)。
集群中的Grain的唯一性由Grain Type+Grain Identity組成。
Grain可以理解為一個服務,類似UserService、AccountService,是主要的業務邏輯實現與抽象
2、Silo
Silo相當於一台服務器,用於存儲Grain,Grain開發完成后需要注冊到Silo中,等待調用
Grain的聲明周期由Silo管理,Grain的聲明周期如下:
銷毀->持久化->激活->在內存中激活->銷毀
其他的Grain或Client會調用目標Grain,Silo運行時去激活Grain(若Grain有狀態,激活時會同時恢復狀態),Grain處理調用請求,Grain閑置,Silo運行時決定是否銷毀Grain,銷毀Grain並從內存中移除(如果Grain有狀態,則需要持久化Grain狀態,以便下次激活時恢復狀態)
Grain作為orleans中的最小執行單元,需要一個運行時去暴露,Silo就是最小的向外提供服務的單元。Silo會通過將相關的Grain進行組裝,暴露一組服務,並在運行時管理Grain的聲明周期。
Silo本身是可以跨平台的。Silo集群是指多個Silo組成的集群,而非多個Orleans Server組成的集群。
3、Client
具體的應用客戶端,Console,Web Application、WPF等.NET端技術。
