基於Golang的游戲服務器框架cellnet開發日記(二)


看官們肯定還有大部分不是很熟悉Actor模型. 我這里基於Erlang, Skynet等語言和框架庫來實戰型解釋下Actor模型.  Actor概念

Actor模型和OO類似, 都是符合人的思維模式進行編碼. OO里啥都是類, 用類來模擬對象, 解決所有的問題. Actor類似的使用Actor來模擬處理對象和單元 

Actor在Erlang中叫進程(非操作系統進程), 在Skynet中叫svc(服務)  Mailbox消息隊列

每個Actor中包含有一個mailbox, 也就是郵箱. Actor自己只能通過收發mailbox與外界進行溝通, 也就是說, Actor之間只能通過消息進行互相交流, 不能采用其他形式. 

mailbox本身是一個順序隊列, 先進先出. 而且mailbox從理論上說沒有上限, 實際上呢, mailbox可能會由於不斷的消息堆積導致內存上漲. 這都是正常的. 

既然mailbox是隊列, 也就代表着一個Actor里的邏輯處理是順序的, 單線程的. 但Actor群體中每個Actor可以獨立處理事務. 因此CPU可以分到每個Actor中進行處理,並發的大業也就奠定了基礎.  Actor的標識: ID

那么, Actor之間的消息要派發, 怎么定位Actor呢? 使用指針?句柄? 都不是的. 

Actor定位使用用ID. 每個Actor有全局唯一的ID, 這里不使用GUID, 因為太難定位了, Erlang選擇了一種優雅的方式實現ID. 先吃一個栗子: 

0.11   1.2   3.5 

這就是Erlang的pid(進程id). 點前面的部分代表的是某個獨立域, 在這個域中通過序號標示每個進程的id,序號就是小數點后面的部分 

那么, 有了ID, 派發消息就變的很簡單了, 看栗子 

send( 來源id,  目標id, 發送內容) 

有來源id的存在, 是為了回發, 或者虛擬來源.  通信自由與部署無關性

有了Actor模型的存在, 邏輯都是分布式編寫, 意思就是掛在每個Actor上來編寫. 而由於Actor模型之間只有消息通信, 沒有函數調用, 指針之類的本地內容. 因此讓Actor的部署變的非常自由. 也就是說, Actor的邏輯, 無需關心自己被部署在1個進程, 還是幾台機器. 但是為了內部性能和傳輸效率的考慮. 能不拆進程, 盡量在同一個進程處理, 能不拆到多台機器, 盡量減少拆到多台機器. 

但當你確實需要並發時, 只需要輕松的修改下設置或者少量代碼, 整個邏輯就可以跑在分布式集群中了

同步和異步

按照Erlang的處理方式, 默認進程(Actor)間使用send發送消息, 這個過程是異步非阻塞的;  當需要同步處理時, 會使用rpc, 也就是使用call的方式進行同步等待, 等對方進程(Actor)收到並處理消息后, 返回結果后, call的調用才結束.

如果call處理中, 其他的Actor給你發消息時, 消息會一直保存在你的Actor的mailbox中, 這里認為mailbox無限大


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM