因爲工做上關係目前常常被各類併發數據問題搞得焦頭爛額,要麼要性能捨棄數據上得一致性,要麼要一致性可是卻獲得了特別糟糕的響應。難道魚和熊掌真的沒法兼得嗎?html
而後找到了相似奧爾良這種基於Actor模型的kuangjia git
首先本人由於是C#系的因此暫不考慮Java系那套,那擺在面前的此類型的框架其實就2個。 Akka.Net和Orleans。github
Actor應該說是一種編程模型,一個Actor是一個最基本的計算單原,他能接收消息並執行計算(一個行爲)編程
它最重要的特性是每一個Actor之間互相隔離,互補共享內存,也就是說每一個Actor都能維持一個私有狀態且不能被別人所改變。多線程
這對於咱們意味着什麼呢?想下通常咱們遇到的併發問題,是否是在咱們執行某個操做的時候,一個數據不正確的被另外一個操做所幹擾,致使數據最終混亂,而Actor則確保本身的數據不能被別人改變(獨立維護本身的狀態)以便使得最終一致。架構
wait併發
若是Actor本身數據不能被別人改變,那就是順序執行?那會不會很慢?框架
對於一個Actor來講,沒錯,他還真的就順序執行,所以能確保準確性性能
可是你真正系統裏確定不會只有一個Actor,而是由不少Actor組成,每一個Actor之間是能並行的(由於他們不共享數據,因此他們能夠互相獨立的正確處理)測試
具體來講,當並行的消息到達一個Actor的時候,它會存儲到一個MailBox(郵箱)裏(你能夠簡單理解爲一個隊列),而後Actor從MailBox撈數據,一條一條順序的撈
而後不一樣的Actor則並行着處理同樣的事情
因爲你們都是互相獨立的處理各自的事情,數據不會發生衝突,也就無需相似鎖之類的機制來確保數據一致性問題
因爲Actor類文章網上搜索一大片, 在此就再也不過多闡述了。
簡單一句話,微軟的一個基於Actor模型的實現,具體介紹能夠更多參考官網
他跟正兒八經的Actor相比,微軟習慣就是將其作更加上層的封裝,Actor都變成了Grains,萬事萬物皆是Grains的感受
我也剛開始入門,發這篇文章主要是想證明下,Actor那套是否是真的那麼神,本文涉及的全部代碼均在 https://github.com/virtualcca/OrleansTest/tree/master 上面
既然他們說他們是以單線程來處理同一個Actor,那我就想測試下用Orleans搞一個併發轉帳的場景,和我常規的多線程併發轉帳場景的一個對比,而我想看到的結果是,常規版的因爲多線程的問題數據老是錯亂的,而奧爾良則能始終正確
轉帳代碼
我有一個帳戶,帳戶上面有Money, 我能作2個操做,要麼轉錢過來,要麼查看我還有多少錢,固然,轉帳總要點時間的對吧,因此轉帳時候Delay了1ms
實際轉帳的執行代碼
能夠注意下奧爾良版和原始版惟一區別在於
奧爾良版是經過client.GetGrain來獲取了一個IAccount,這樣獲取到的是屬於奧爾良託管的一個Client實例,對其執行的操做其實會發送到Host裏執行,而後Host裏就是正兒八經的Actor架構來去處理全部操做
可是正如以前介紹Actor的時候談到單個Actor是單線程,而多個Actor之間是併發,如何肯定你是一個仍是多個Actor,是經過一個Id來區分(具體奧爾良官網有介紹),而GetGrain後面的那個0的參數就是他的Id,也就是個人這個IAccount是屬於一個Actor
常規版直接new一個實例執行一樣操做
而後代碼運行,能夠看到結果
原始版的結果僅供參考,我每次運行得出來的結果也都不同(多線程執行順序是不肯定的)
而奧爾良版則能正確的恆定輸出4950
至此,能夠明確奧爾良完美的實現了Actor裏關於單個Actor單線程的這麼個處理。。。。