1. 程式人生 > >Pomelo術語解釋

Pomelo術語解釋

gate伺服器

一個應用的gate伺服器,一般不參與rpc呼叫,也就是說其配置項裡可以沒有port欄位,僅僅有clientPort欄位,它的作用是做前端的負載均衡。客戶端往往首先向gate伺服器發出請求,gate會給客戶端分配具體的connector伺服器。具體的分配策略一般是根據客戶端的某一個key做hash得到connector的id,這樣就可以實現各個connector伺服器的負載均衡。

connector伺服器

connector伺服器接收客戶端的連線請求,建立與客戶端的連線,維護客戶端的session資訊。同時,接收客戶端對後端伺服器的請求,按照使用者配置的路由策略,將請求路由給具體的後端伺服器。當後端伺服器處理完請求或者需要給客戶端推送訊息的時候,connector伺服器同樣會扮演一箇中間角色,完成對客戶端的訊息傳送。connector伺服器會同時擁有clientPort和port,其中clientPort用來監聽客戶端的連線,port埠用來給後端提供服務。

應用邏輯伺服器

gate伺服器和connector伺服器又都被稱作前端伺服器,應用邏輯伺服器是後端伺服器,它完成實際的應用邏輯,提供服務給客戶端,當然客戶端的請求是通過前端伺服器路由過來的。後端伺服器之間也會通過rpc呼叫而有相互之間的互動。由於後端伺服器不會跟客戶端直接有連線,因此後端伺服器只需監聽它提供服務的埠即可。

master伺服器

master伺服器載入配置檔案,通過讀取配置檔案,啟動所配置的伺服器叢集,並對所有伺服器進行管理。

rpc呼叫

pomelo中使用rpc呼叫進行程序間通訊,在pomelo中rpc呼叫分為兩大類,使用namespace進行區分,namespace為sys的為系統rpc呼叫,它對使用者來說是透明的,目前pomelo中系統rpc呼叫有:

  • 後端伺服器向前端伺服器請求session資訊
  • 後端伺服器通過channel推送訊息時對前端伺服器發起的rpc呼叫
  • 前端伺服器將使用者請求路由給後端伺服器時也是sys rpc呼叫 除了系統rpc呼叫外,其餘的由使用者自定義的rpc呼叫屬於user namespace的rpc呼叫,需要使用者自己完成rpc服務端remote的handle程式碼,並由rpc客戶端顯式地發起呼叫

route,router

route用來標識一個具體服務或者客戶端接受服務端推送訊息的位置,對服務端來說,其形式一般是..,例如"chat.chatHandler.send", chat就是伺服器型別,chatHandler是chat伺服器中定義的一個Handler,send則為這個Handler中的一個handle方法。對客戶端來說,其路由一般形式為onXXX,當服務端推送訊息時,客戶端會有相應的回撥。 一般來說具體的同類型應用伺服器都會有多個,當客戶端請求到達後,前端伺服器會將使用者客戶端請求派發到後端伺服器,這種派發需要一個路由函式router,可以粗略地認為router就是根據使用者的session以及其請求內容,做一些運算後,將其對映到一個具體的應用伺服器id。可以通過application的route呼叫給某一型別的伺服器配置其router。如果不配置的話,pomelo框架會使用一個預設的router。pomelo預設的路由函式是使用session裡面的uid欄位,計算uid欄位的crc32校驗碼,然後用這個校驗碼作為key,跟同類應用伺服器數目取餘,得到要路由到的伺服器編號。注意這裡有一個陷阱,就是如果session沒有繫結uid的話,此時uid欄位為undefined,可能會造成所有的請求都路由到同一臺伺服器。所以在實際開發中還是需要自己來配置router。

Session, FrontendSession, BackendSession, SessionService, BackendSessionService

在pomelo框架中,有這三個session的概念,同時又有兩個service:SessionServiceBackendSessionService,也是最令人迷惑的地方,這裡嘗試給出一些說明,讓你的理解更清晰一些: Session的是一個客戶端連線的抽象,它的大致欄位如下:

{
    id : <session id> // readonly
    frontendId : <frontend server id> // readonly
    uid : <bound uid> // readonly
    settings : <key-value map> // read and write  
    __socket__ : <raw_socket>
    __state__ : <session state>

    // ...
}
  • id是這個session的id,是全域性唯一的,一般使用自增的方式來生成;
  • frontendId是維護這個session的前端伺服器的id;
  • uid是這個session所繫結的使用者id;
  • __socket__是底層原生socket的引用;
  • __state__用來指明當前session的生命週期狀態。
  • settings維護一個key-value map,用來描述session的一些自定義屬性,比如聊天應用中的房間號就可以看作是session的一個自定義屬性。

從上面的分析看,一個session一旦建立,那麼id, frontendId,__socket__, __state__, uid都是確定的,都應該是隻可讀不可寫的。而settings也不應該被隨意的修改。 因此,在前端伺服器中,引入了FrontendSession, 可以把它看作是一個內部session在前端伺服器中的傀儡,FrontendSession的欄位大致如下:

{
    id : <session id> // readonly
    frontendId : <frontend server id> // readonly
    uid : <bound uid> // readonly
    settings : <key-value map> // read and write  
}

其作用:

  • 通過FrontendSession可以對settings欄位進行設定值,然後通過呼叫FrontendSession的push方法,將設定的settings的值同步到原始session中;
  • 通過FrontendSession的bind呼叫,還可以給session繫結uid;
  • 當然也可以通過FrontendSession訪問session的只讀欄位,不過對FrontendSession中與session中相同的只讀欄位的修改並不會反映到原始的session中。

SessionService維護所有的原始的session資訊,包括不可訪問的欄位,繫結的uid以及使用者自定義的欄位。

下面再說BackendSession,與FrontendSession類似,BackendSession是用於後端伺服器的,可以看作是原始session的代理,其資料欄位跟FrontendSession基本一致。

BackendSession是由BackendSessionService建立並維護的,在後端伺服器接收到請求後,由BackendSessionService根據前端伺服器rpc的引數,進行建立。對BackendSessionService的每一次方法呼叫實際上都會生成一個遠端呼叫,比如通過一個sid獲取其BackendSession。同樣,對於BackendSession中欄位的修改也不會反映到原始的session中,不過與FrontendSession一樣,BackendSession也有push,bind,unbind呼叫,它們的作用與FrontendSession的一樣,都是用來修改原始session中的settings欄位或者繫結/解綁uid的,不同的是BackendSession的這些呼叫實際上都是名字空間為sys的遠端呼叫。

Channel

channel可以看作是一個玩家id的容器,主要用於需要廣播推送訊息的場景。可以把某個玩家加入到一個Channel中,當對這個Channel推送訊息的時候,所有加入到這個Channel的玩家都會收到推送過來的訊息。一個玩家的id可能會被加入到多個Channel中,這樣玩家就會收到其加入的Channel推送過來的訊息。需要注意的是Channel都是伺服器本地的,應用伺服器A和B並不會共享Channel,也就是說在伺服器A上建立的Channel,只能由伺服器A才能給它推送訊息。

request, response, notify, push

pomelo中有四種訊息型別的訊息,分別是request,response,notify和push,客戶端發起request到伺服器端,伺服器端處理後會給其返回響應response;notify是客戶端發給服務端的通知,也就是不需要服務端給予回覆的請求;push是服務端主動給客戶端推送訊息的型別。在後面的敘述中,將會使用這些術語而不再作解釋。

filter

filter分為before和after兩類,每類filter都可以註冊多個,形成一個filter鏈,所有的客戶端請求都會經過filter鏈進行一些處理。before filter會對請求做一些前置處理,如:檢查當前玩家是否已登入,列印統計日誌等。after filter是進行請求後置處理的地方,如:釋放請求上下文的資源,記錄請求總耗時等。after filter中不應該再出現修改響應內容的程式碼,因為在進入after filter前響應就已經被髮送給客戶端。

handler

handler是實現具體業務邏輯的地方,在請求處理流程中,它位於before filter和after filter之間,handler的介面宣告如下:

handler.methodName = function(msg, session, next) {
  // ...
}

引數含義與before filter類似。handler處理完畢後,如有需要返回給客戶端的響應,可以將返回結果封裝成js物件,通過next傳遞給後面流程。

error handler

error handler是一個處理全域性異常的地方,可以在error handler中對處理流程中發生的異常進行集中處理,如:統計錯誤資訊,組織異常響應結果等。error handler函式是可選的,如果需要可以通過

app.set('errorHandler', handleFunc);

來向pomelo框架進行註冊,函式宣告如下:

errorHandler = function(err, msg, resp, session, next) {
  // ...
}

其中,err是前面流程中發生的異常;resp是前面流程傳遞過來,需要返回給客戶端的響應資訊。其他引數與前面的handler一樣。

component

pomelo 框架是由一些鬆散耦合的component組成的,每個component完成一些功能。整個pomelo框架可以看作是一個component容器,完成component的載入以及生命週期管理。pomelo的核心功能都是由component完成的,每個component往往有start,afterStart,stop等呼叫,用來完成生命週期管理。

admin client, monitor, master

在對pomelo伺服器進行管理的時候,有三個概念admin client, monitor, master。

  • monitor執行在各個應用伺服器中,它會向master註冊自己,向master上報其伺服器的資訊,當伺服器群有變化時,接收master推送來的變化訊息,更新其伺服器上下文。

  • master執行在應用伺服器中,它會收集整個伺服器群的資訊,有變化時會將變化推送到各個monitor;同時,master還接受admin client的請求,按照client發出的命令,執行對應的操作,如查詢整個伺服器群的狀態,增加一個伺服器等。

  • client獨立執行自己的程序,它會發起到master的連線,然後通過對master發出請求或者命令,來管理整個伺服器群。目前工具pomleo-cli就是這樣的一個客戶端。

admin module

在pomelo中,module特指伺服器監控管理模組,與component類似,不過在module中實現的是監控邏輯,比如收集程序狀態等。使用者在使用時,可以通過applicationregisterAdmin註冊管理模組,實現使用者自己定製的監控管理功能。每一個module中都會定義下面四種回撥函式,不過都是可選的:

  • masterHandler(agnet, msg, cb) 當有應用伺服器給master發監控資料時,這個回撥函式會由master程序進行回撥,完成應用伺服器的訊息處理;
  • monitorHandler(agent, msg, cb) 當有master請求應用伺服器的一些監控資訊時,由應用伺服器進行回撥,完成對master請求的處理;
  • clientHandler(agent, msg, cb)當由管理客戶端向master請求伺服器群資訊時,由master程序進行回撥處理客戶端的請求。
  • start(cb) 當admin module,註冊載入完成後,這個回撥會被執行,在這裡可以做一些初始化工作。

plugin

plugin是pomelo 0.6加入的全新的擴充套件機制,一個plugin由多個component以及一些事件響應處理器組成。它提供了一種很靈活的機制來擴充套件pomelo。不僅可以提供component的功能,還可以對整個框架的全域性事件作出響應處理。

轉自https://www.cnblogs.com/fuland/p/4000345.html