Orleans簡單配置
這是Orleans系列文章中的一篇.首篇文章在此
話說曾幾何時,我第一次看到xml文件,心中閃過一念想:"這<>是什么鬼?"…用ini或者json多簡單易懂,現在發覺作為配置文件,json有趕超xml的趨勢.不過xml用多了,也覺得順眼多了.不覺得<>難看了,反而它能折疊讓我覺得組織起來也更方便了.這說明一個道理:不是你上了大學,而是大學上了你.你覺得痛苦到方便的過程,就是這種轉變的佐證.所以C++又名C艹.你們細細體會一下.
Orleans完全體,分為Orleans客戶端以及Orleans服務端,所以配置也應對與這兩方面.再Orleans源碼里也可以看出來,如下截圖:
其中cluster就是服務端配置,client就是客戶端配置.說一說cluster,起個名字就叫cluster說明再實際應用中,單個siloHost不能滿足Orleans小組的需求,可以聽到Orleans君吶喊說:我天生就是為cluster的.瞬間覺得我舉得栗子,單silo的例子是個low X.不過沒事..微軟還舉了個例子,甚至把四個項目(client,host,接口,以及Grain實現)都放在了一個項目中.有空可以去看看.
確實,如果不是為了分布式,Orleans帶來的好處就少了許多,單silo帶來的好處就是,編寫多線程程序的時候,邏輯變清晰了,出錯少了.可以這么說,多線程要是沒有鎖,難度就減少了一大半了.但是分布式,分布式,分布式…就算是不需要鎖,分布式一樣很難.Orleans的出現讓分布式的難度又降低了一大半.
基於編程的配置,在介紹完基於文件的配置之后,各位觀眾可以自己研究.vs中需要引入OrleansConfiguration.xsd文件才能更好的利用智能提示來配置.這個文件在Orleans源碼中有.
客戶端配置
客戶端的配置非常簡單,假設此文件名字叫做client.xml
<ClientConfiguration xmlns="urn:orleans"> <Gateway Address="192.168.1.1" Port="30000"/> <Gateway Address="192.168.1.2" Port="30000"/> <Gateway Address="192.168.1.3" Port="30000"/> </ClientConfiguration>
使用它也很簡單:如下圖
這些Gateway顯然對應着silo提供的端口和網址,通常來說這些關口配置一個就可以了.不過配置多個可以幫助提高穩定性(前提是silo存在).在1.5版本以及之后,Orleans提供了一個非靜態的GrainClient類,名字是ClientBuilder.一個客戶端可以有多個Client了..每個client可以有不同的 配置文件.選擇一下子又多了起來.
以上的配置是基於silo的地址端口固定的情況,但是Orleans支持服務發現,特別是在基於集群的配置的時候.client甚至不知道silo的地址在哪,它只需要查詢"服務發現"的服務.這個服務返回現在活着的silo的地址.client連接這些地址.基於集群的客戶端配置是如下格式:
<ClientConfiguration xmlns="urn:orleans"> <SystemStore SystemStoreType="SqlServer" DeploymentId="target deployment ID" DataConnectionString="SQL connection string"/> </ClientConfiguration>
這樣可以使用sql server作為服務發現的服務.並不是隨便的sql server都可以作為服務發現用的.在源代碼中官方提供了一些sql腳本.通過這個sql腳本構建好數據庫,就可以用來服務發現了.
用數據庫作為服務發現是很好的選擇,不過我沒有采用它,我是基於以下考慮的:數據庫還要作為數據持久化設備,還要作為event sourcing.還要錢…我采用了更為輕量化的方案.這個不是本文的重點.關於集群的配置方法我會在以后的文章中舉個栗子.現在文章的目的是為了引入持久化.所以就暫時按住不表.且待我接着說存儲的配置.好了客戶端的基本配置就結束了.(構建集群的配置會再后邊文章詳細說說,這里先稍微引入一下)
說說重頭戲,服務端配置,就像上邊截圖中列示的一樣,服務端配置就是cluster的配置!!!哈哈,怕了嗎?
為了測試和開發,可以如下配置本地的silo
<OrleansConfiguration xmlns="urn:orleans"> <Globals> <SeedNode Address="localhost" Port="11111" /> </Globals> <Defaults> <Networking Address="localhost" Port="11111" /> <ProxyingGateway Address="localhost" Port="30000" /> </Defaults> </OrleansConfiguration>
Orleans簡單配置---服務端
這個世界有太多太多的選擇了,大部分時候選擇太多才是我苦惱的主要原因,為了某個組織方式,要和自己討論,好不容易說服自己,又要和其他人討論,到最后一般被否決(黑臉).不管怎么說,選擇困難是人類的通病,沒得選,大部分時候反而更能提高效率.所以說,這讓我們明白一個道理:少讀點書,讓自己沒得選,生活會更幸福. 當你看到不明白的地方,皺着眉頭思索着,仿佛自己都能聽到自己腦袋咔咔作響,感覺這就是你腦結構改變的過程.其實這是錯覺,本質上還是因為犯愁.選擇困難症又犯了,大腦不知道該喚醒那塊區域…
以上這一段更本文有很大關系.
服務端配置主要是有兩個方面,由於silo要與其他silo之間進行聯系,組成一個集群,而且它還需要和client通信,所以它需要配置兩個端口.一個用於silo間的通信,一個用於與client的通信.服務端需要配置關於集群的各個信息和關於自己節點的各個信息.所以總體來說服務端配置長成這樣子
分兩個節:Globals節和Defaults節.Globals里面都是關於集群的配置,而Defaults里面都是關於自己節點的配置.
既然說到集群,就不得不誇誇Orleans了.Orleans的集群在客戶端看來,就仿佛是一個silo.而且對於silo內部運行的Grain類實例看來,也仿佛是一個silo.這樣做的好處就是,你開發的時候使用單例silo進行開發,然后通過配置服務發現,配置持久化,以及把silo多復制幾份,就可以做到分布式了.背后太多的工作都是Orleans完成的.同時Orleans還提供了檢測機制,用於探測集群內部崩潰,掉線等原因而無法鏈接到的silo,以及新加入的silo等等.這些集群節點的變動對於Grain實例以及客戶端來說,大部分情況都無需關心(仍需要關心小部分情況,比如所有節點都崩潰等等).
分布式程序中,一致性是一個重要的問題,Orleans集群內部維持一個MembershipTable(成員關系表),所有的集群節點都需要維持自己的成員關系表.所以在silo啟動的時候會有如下記錄:
這個表在集群的行為上發揮着重要的作用,這個按下不表,說一說山東好漢塞嘍(silo).
要知道塞嘍在Orleans中是一個實體類,但是集群不是,賽嘍不知道集群的存在,它只知道按照配置文件與其他silo互動,這些所有的互動行為的結果,讓人感覺它們合體了,是一個整體,這個整體有一個新的名字是梁山聚義堂.所以嚴格意義上來說,集群內部的silo中的Globals節點的配置可以不同.因為它就是告訴silo如何和其他silo進行互動的.但是我想沒有人這么干(配置文件不相同).這是給自己添堵.
一個簡單的服務端配置,如下圖
可以看出來,這個節點本質上就是集群的主節點.membershipTable需要找一個地方存儲,默認的是內存保存這個成員關系表,怎么看出來的?如下圖
其中的GrainBasedMembershipTable就是Orleans用一個內置的Grain類管理了成員關系表.
之前說過成員關系表最終是要在各個silo之間統一的.所以在一個集群中如果有主silo,那么所有非主silo的成員關系表,就需要和主silo的統一.在從silo的日志中可以看到這樣的記錄
經過以上配置,一個簡單的silo集群主silo就形成了.
現在我把從silo的配置文件也一起貼出來,大家看看變化,
雖然這個集群是可以工作的,但是不符合穩定性,而且靈活性也不夠.因為如果主silo掛了,整個集群就掛了.在集群配置的時候,主要考慮以哪里的成員關系表為標准在集群內進行統一.正如前面說的,可以用數據庫存儲成員關系表.這樣的配置文件就需要有所變化.至於如何變化,會再后續的文章中詳細說明,比較集群的配置是Orleans的一項重要內容.所以在此暫且按下不表,說一說,引入配置的原因,那就是介紹如何持久化grain數據.