skynet是什麼

來源:互聯網
上載者:User

標籤:

     雲風的skynet,定義為一個遊戲伺服器架構,用c + lua基於Actor模型實現。代碼極其精簡,c部分的代碼只有三千行左右。     整個skynet架構要解決的核心問題是:把一個訊息(資料包)從一個服務(Actor)發送給另一個服務(Actor),並接收其返回。也就是在同一進程內(作者也強調並非只限於同一進程,因為可能會有叢集間的通訊)的一個服務通過類似rpc之類的調用同一進程內的另外一個服務,並接收處理結果。而skynet就是處理這些服務間發送資料包的規則和正確性。     skynet的核心層全部是c來實現。     當系統啟動的時候,會得到一個提前分配好的節點id,我們稱之為harbor id,這個id是叢集用的,一個叢集內可以啟動很多個skynet節點,每個節點都會分配到唯一的id。     一個節點(即一個進程)內有很多個服務,服務可以狹義地暫且理解為功能模組。     當初始化一個服務的時候,會產生一個skynet_context來作為服務的執行個體;一個唯一(即使是在叢集裡也是唯一)的服務handle,即服務的唯一id,用來識別服務;一個訊息佇列message_queue;還要向架構註冊一個callback,當服務收到有發送來的訊息時,通過這個方法傳入。     初始化一個服務的代碼如下: 
struct skynet_context *skynet_context_new(const char * name, const char *param) {     // 裝載模組     struct skynet_module * mod = skynet_module_query(name);     if (mod == NULL)          return NULL;     void *inst = skynet_module_instance_create(mod);     if (inst == NULL)          return NULL;     // 初始化skynet_context執行個體     struct skynet_context * ctx = skynet_malloc(sizeof(*ctx));     CHECKCALLING_INIT(ctx)     ctx->mod = mod;     ctx->instance = inst;     ctx->ref = 2;     ctx->cb = NULL;     ctx->cb_ud = NULL;     ctx->session_id = 0;     ctx->logfile = NULL;     ctx->init = false;     ctx->endless = false;     // 初始化服務handle     // Should set to 0 first to avoid skynet_handle_retireall get an uninitialized handle     ctx->handle = 0;         ctx->handle = skynet_handle_register(ctx);     // 初始化訊息佇列     struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);     // init function maybe use ctx->handle, so it must init at last     context_inc();     CHECKCALLING_BEGIN(ctx)     int r = skynet_module_instance_init(mod, inst, ctx, param);     CHECKCALLING_END(ctx)     if (r == 0) {          struct skynet_context * ret = skynet_context_release(ctx);          if (ret) {               ctx->init = true;          }          skynet_globalmq_push(queue);          if (ret) {               skynet_error(ret, "LAUNCH %s %s", name, param ? param : "");          }          return ret;     } else {          skynet_error(ctx, "FAILED launch %s", name);          uint32_t handle = ctx->handle;          skynet_context_release(ctx);          skynet_handle_retire(handle);          struct drop_t d = { handle };          skynet_mq_release(queue, drop_message, &d);          return NULL;     }}

     在skynet_handle_register方法中產生一個服務handle,handle是一個32位的整數,在產生handle的時候,是把該節點的harbor id寫到了handle的高8位裡面,所以一個服務的handle,就可以知道這個服務是哪個節點的。

          s->handle_index = handle + 1;          rwlock_wunlock(&s->lock);          handle |= s->harbor;          return handle;    
所以說,harbor id最高也只有256個,也就意味著skynet叢集最多隻能有256個節點,而一個節點裡最多也只能有24位個服務,即1.6M個。因為一個handle是32位的整數,高8位用來儲存harbor id,只有低的24位用來分配給本節點的handle。     訊息佇列message_queue是用來儲存發送給該服務的訊息的。所有發送給該服務的訊息,都要先壓到該服務的訊息佇列中。      服務啟動起來了,來看看資料包是如何從一個服務發送給另一個服務的。     來看看 skynet_send 和 callback 函數的定義:
int skynet_send(  struct skynet_context * context,  uint32_t source,  uint32_t destination,  int type,  int session,  void * msg,  size_t sz);typedef int (*skynet_cb)(  struct skynet_context * context,  void *ud,  int type,  int session,  uint32_t source ,  const void * msg,  size_t sz);
source和destination分別是發送方和接收方的handle。type是發送方和接收方處理資料包的協議session識別本次調用的口令,發送方發送一個訊息後,保留該session,以便收到回應資料包時,能識別出是哪一次調用。msg/sz是資料包的內容和長度,成對使用 skynet 的訊息調度 Skynet 維護了兩級訊息佇列。 每個服務實體有一個私人的訊息佇列,隊列中是一個個發送給它的訊息。訊息由四部分構成: struct skynet_message {    uint32_t source;    int session;    void * data;    size_t sz;};向一個服務發送一個訊息,就是把這樣一個訊息體壓入這個服務的私人訊息佇列中。這個結構的值複製進訊息佇列的,但訊息內容本身不做複製。 Skynet 維護了一個全域訊息佇列,裡面放的是諸個不為空白的次級訊息佇列。 在 Skynet 啟動時,建立了若干背景工作執行緒(數量可配置),它們不斷的從主訊息列隊中取出一個次級訊息佇列來,再從次級隊列中取去一條訊息,調用對應的服務的 callback 函數進行出來。為了調用公平,一次僅處理一條訊息,而不是耗淨所有訊息(雖然那樣的局部效率更高,因為減少了查詢服務實體的次數,以及主訊息佇列進出的次數),這樣可以保證沒有服務會被餓死。 這樣,skynet就實現了把一個訊息(資料包)從一個服務發送給另一個服務。 

 參考:Skynet 設計綜述

 

    風瀟瀟

skynet是什麼

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.