1. 程式人生 > >skynet框架應用 (一) skynet介紹

skynet框架應用 (一) skynet介紹

1 skynet介紹

​ Skynet 是一個基於C跟lua的開源服務端併發框架,這個框架是單程序多執行緒Actor模型。是一個輕量級的為線上遊戲伺服器打造的框架。

我在雲風部落格的基礎上,把重要的知識點加上具體的example來講解skynet如何去使用。前面的比較囉嗦一些,大家不想了解這些知識的,可以直接跳轉到第二章節。

1.1 簡介

​ 這個系統是單程序多執行緒模型。

​ 每個服務都是嚴格的被動的訊息驅動的,以一個統一的 callback 函式的形式交給框架。框架從訊息佇列裡排程出接收的服務模組,找到 callback 函式入口,呼叫它。服務本身在沒有被排程時,是不佔用任何 CPU 的。

​ skynet雖然支援叢集,但是作者雲風主張能用一個節點完成儘量用一個節點,因為多節點通訊方面的開銷太大,如果一共有 100 個 skynet 節點,在它們啟動完畢後,會建立起 9900條通訊通道。

1.2 特點

Skynet框架做兩個必要的保證:

一、一個服務的 callback 函式永遠不會被併發。

二、一個服務向另一個服務傳送的訊息的次序是嚴格保證的。

​ 用多執行緒模型來實現它。底層有一個執行緒訊息佇列,訊息由三部分構成:源地址、目的地址、以及資料塊。框架啟動固定的多條執行緒,每條工作執行緒不斷從訊息佇列取到訊息,呼叫服務的 callback 函式。

​ 執行緒數應該略大於系統的 CPU 核數,以防止系統飢餓。(只要服務不直接給自己不斷髮新的訊息,就不會有服務被餓死)

​ 對於目前的點對點訊息,要求傳送者呼叫 malloc 分配出訊息攜帶資料用到的記憶體;由接受方處理完後呼叫 free 清理(由框架來做)。這樣資料傳遞就不需要有額外的拷貝了。

​ 做為核心功能,Skynet 僅解決一個問題:

​ 把一個符合規範的 C 模組,從動態庫(so 檔案)中啟動起來,繫結一個永不重複(即使模組退出)的數字 id 做為其 handle 。模組被稱為服務(Service),服務間可以自由傳送訊息。每個模組可以向 Skynet 框架註冊一個 callback 函式,用來接收發給它的訊息。每個服務都是被一個個訊息包驅動,當沒有包到來的時候,它們就會處於掛起狀態,對 CPU 資源零消耗。如果需要自主邏輯,則可以利用 Skynet 系統提供的 timeout 訊息,定期觸發。

1.3 Actor模型

1.3.1 Actor模型介紹

​ **Actor模型內部的狀態由它自己維護即它內部資料只能由它自己修改(通過訊息傳遞來進行狀態修改),所以使用Actors模型進行併發程式設計可以很好地避免這些問題,Actor由狀態(state)、行為(Behavior)和郵箱(mailBox)三部分組成**

  1. 狀態(state):Actor中的狀態指的是Actor物件的變數資訊,狀態由Actor自己管理,避免了併發環境下的鎖和記憶體原子性等問題

  2. 行為(Behavior):行為指定的是Actor中計算邏輯,通過Actor接收到訊息來改變Actor的狀態

  3. 郵箱(mailBox):郵箱是Actor和Actor之間的通訊橋樑,郵箱內部通過FIFO訊息佇列來儲存傳送方Actor訊息,接受方Actor從郵箱佇列中獲取訊息

Actor的基礎就是訊息傳遞,skynet中每個服務就是一個LUA虛擬機器,就是一個Actor。

1.3.2 Actor模型好處

  1. 事件模型驅動: Actor之間的通訊是非同步的,即使Actor在傳送訊息後也無需阻塞或者等待就能夠處理其他事情。

  2. 強隔離性: Actor中的方法不能由外部直接呼叫,所有的一切都通過訊息傳遞進行的,從而避免了Actor之間的資料共享,想要觀察到另一個Actor的狀態變化只能通過訊息傳遞進行詢問。

  3. 位置透明: 無論Actor地址是在本地還是在遠端機上對於程式碼來說都是一樣的。

  4. 輕量性:Actor是非常輕量的計算單機,只需少量記憶體就能達到高併發。