網易游戲服務器開發框架,Pomelo 0.7 版正式發布!
pomelo 是由網易開發的基于node.js開發的高性能、分布式游戲服務器框架, 也可作為高實時web應用框架。
Pomelo的應用范圍
pomelo最適合的應用領域是網頁游戲、社交游戲、移動游戲的服務端,開發者會發現pomelo可以用如此少的代碼達到強 大的擴展性和伸縮性。當然還不僅僅是游戲,很多人斷言未來的web時代是實時web應用的時代, 我們發現用pomelo開發高實時web應用也如此合適, 而且伸縮性比其它框架好。目前不推薦將pomelo用于大型的MMO rpg游戲開發,尤其是3d游戲, 還是需要象bigworld這樣的商用引擎來支撐。
Pomelo的理念
pomelo的第一個理念是讓游戲(高實時web應用)服務器的開發變得非常簡單, 而不是解決某類算法或系統上的難題。這個設計理念跟rails是很類似的;第二個理念是重視性能和可伸縮性,用戶用pomelo開發出來的游戲天生具有很 強的伸縮性,擴展也很容易。我們在性能優化上也花了很多功夫,并且會持續進行;第三個理念是讓第三方很容易擴展,框架用了很多插件式的設計, 組件component、路由規則、甚至管理控制臺都可以完全由第三方擴展。
Pomelo的框架組成
pomelo包括三部分:
- 框架, pomelo的核心, 與以往單進程的游戲框架不同, 它是高性能、分布式的游戲服務器框架,并且使用很簡單
- 庫, 包括了開發游戲的常用工具庫, 如人工智能(ai), 尋路, aoi等
- 工具包, 包括管理控制臺, 命令行工具, 壓力測試工具等
pomelo特性
- 快速、易上手的游戲開發模型和api
- 高可伸縮的多進程架構, 支持MMO的場景分區和其它各類分區策略
- 方便的服務器擴展機制,可快速擴展服務器類型和數量
- 方便的請求、響應、廣播、服務器通訊機制, 無需任何配置
- 注重性能,在性能、可伸縮性上做了大量的測試、優化
- 提供了較多擴展組件,包括游戲開發常用的庫和工具包
- 提供了完整的MMO demo代碼(客戶端html5),可以作為很好的開發參考
- 基于socket.io開發,支持socket.io支持的多種語言客戶端
為什么使用pomelo?
高并發、高實時的游戲服務器的開發是很復雜的工作。跟web應用一樣, 一個好的開源容器或開發框架可以大大減少游戲開發的復雜性,讓開發變得更加容易。
遺憾的是目前在游戲服務器開發領域一直沒有太好的開源解決方案。 pomelo將填補這個空白, 打造一款完全開源的高性能(并發)游戲服務器框架。 pomelo的優勢有以下幾點:
- 架構的可伸縮性好。 采用多進程單線程的運行架構,擴展服務器非常方便, node.js的網絡io優勢提供了高可伸縮性。
- 使用非常容易, 開發模型與web應用的開發類似,基于convention over configuration的理念, 幾乎零配置, api的設計也很精簡, 很容易上手。
- 框架的松耦合和可擴展性好, 遵循node.js微模塊的原則, framework本身只有很少的代碼,所有component、庫、工具都可以用npm module的形式擴展進來。任何第三方都可以根據自己的需要開發自定義module。
- 提供完整的開源MMO游戲demo參考(基于HTML 5)。 一個超過1萬行代碼的游戲demo,使開發者可以隨時借鑒demo的設計與開發思路。
在線演示:http://pomelo.netease.com/demo.html
在pomelo 0.7版本中,增加了用戶自定義定時任務功能,用戶能夠在不同服務器中動態地增刪定時任務;根據網友的建議,在0.7版中增加了全局filter的功能, 用戶能夠在前端服務器對請求進行統一處理;另外新版中增加了事務的機制,提供了一個簡單的事務方法,包括條件方法和處理方法;其它新特性還包括pomelo-cli的命令自動補全功能。
定時任務
用戶能夠通過配置文件或者pomelo-cli的命令addCron和removeCron對定時任務進行動態調度。
定時任務是針對具體服務器而言,例如需要在chat服務器中配置定時任務:
首先在game-server/app/servers/chat目錄下增加cron目錄,在game-server/app/servers/chat/cron目錄下編寫具體的執行的任務的代碼chatCron.js,例如:
module.exports = function(app) { return new Cron(app); }; var Cron = function(app) { this.app = app; }; var cron = Cron.prototype; cron.sendMoney = function() { console.log('%s server is sending money now!', this.app.serverId); };
然后在game-server/config/目錄下增加定時任務配置文件crons.json,具體配置文件如下所示:
{ "development":{ "chat":[ {"id":1, "time": "0 30 10 * * *", "action": "chatCron.sendMoney"}, {"id":2, "serverId":"chat-server-1", "time": "0 30 10 * * *", "action": "chatCron.sendMoney"} ] }, "production":{ "chat":[ {"id":1, "time": "0 30 10 * * *", "action": "chatCron.sendMoney"}, {"id":2, "serverId":"chat-server-1", "time": "0 30 10 * * *", "action": "chatCron.sendMoney"} ] } }
在配置文件crons.json中,id是定時任務在具體服務器的唯一標識,且不能在同一服務器中重復;time是定時任務執行的具體時間,時間的定義跟linux的定時任務類似,一共包括7個字段,每個字段的具體定義如下:
* * * * * * command to be executed - - - - - - | | | | | | | | | | | +----- day of week (0 - 6) (Sunday=0) | | | | +------- month (1 - 12) | | | +--------- day of month (1 - 31) | | +----------- hour (0 - 23) | +------------- min (0 - 59) +------------- second (0 - 59)
0 30 10 * * * 這就代表每天10:30執行相應任務;serverId是一個可選字段,如果有寫該字段則該任務只在該服務器下執行,如果沒有該字段則該定時任務在所有同 類服務器中執行;action是具體執行任務方法,chatCron.sendMoney則代表執行game-server/app/servers /chat/cron/chatCron.js中的sendMoney方法。
通過pomelo-cli的addCron和removeCron命令可以動態地增加和刪除定時任務,其中addCron的必要參數包括:id,action,time;removeCron的必要參數包括:id;serverId和serverType是兩者選其一即可。例如:
addCron id=8 'time=0 30 11 * * *' action=chatCron.sendMoney serverId=chat-server-3 removeCron id=8
全局filter
在之前pomelo的版本中,filter是在后端服務器進行消息攔截并進行相應處理;根據網友的意見,在0.7版中在前端服務器增加了 filter,請求在前端服務器就可以進行統一處理。請求的處理過程由之前的:前端服務器 -> beforeFilter -> 后端服務器 -> afterFilter 變為:globalBeforeFilter -> 前端服務器 -> beforeFilter -> 后端服務器 -> afterFilter -> globalAfterFilter。同之前的filter的錯誤處理過程一樣,全局filter的錯誤全部進入globalErrorHandler處 理。
全局filter與以前的filter可以相互通用,具體的配置樣例如下:
app.configure('production|development', function() { app.globalFilter(pomelo.serial()); });
Transaction
在新版本中,pomelo提供簡單的事務處理的功能;開發者可以設置相應的事務處理條件和實際事務處理的方法,同時開發還可以定義事務處理的重試次 數。事務的具體執行過程是先執行開發者定義的事務處理條件,如果條件報錯則直接終止整個事務,如果條件執行通過,再開始執行相應的事務處理方法,當在事務 處理方法執行的過程中出現錯誤則根據開發者定義的重試次數進行執行重試,默認重試次數為1;所有的事務處理的結果都會在相應的日志文件中進行詳細記錄,開 發者可以根據錯誤日志對失敗的事務進行相應處理;相應的API如下所示:
transaction(name, conditions, handlers, retry)
事務處理方法
Arguments
+ name - transaction name
+ conditions - transaction conditions
+ handlers - transaction handlers
+ retry - retry times of handlers if error occurs in handlers
具體的使用示例如下:
var conditions = { test1: function(cb) { console.log('condition1'); cb(); }, test2: function(cb) { console.log('condition2'); cb(); } }; var handlers = { do1: function(cb) { console.log('handler1'); cb(); }, do2: function(cb) { console.log('handler2'); cb(); } }; app.transaction('test', conditions, handlers, 3);
pomelo-cli自動提示
在最新版本的pomelo-cli中提供命令自動補全的功能,具體可以參考pomelo-cli。
pomelo 部分術語改名
在最新版本中,對pomelo中一些含混并且可能對用戶造成誤導的命名做了修改,這樣可以使得名字含義更明確,以使得開發者能更好地理解,具體修改如下:
- LocalSession以及LocalSessionService改名為BackendSession和BackendSessionService,具體功能不變,代碼中需要注意如下:
// deprecated var localSessionService = app.get("localSessionService"); // recommanded var backendSessionService = app.get("backendSessionService");
- MockLocalSession 修改為 FrontendSession。
-
組件scheduler改名為pushScheduler, 對pushScheduler組件進行配置選項的時候使用:
app.set("pushSchedulerConfig", opts);
-
組件proxy以及remote的配置選項 cacheMsg 本版本中改名為bufferMsg,使得含義更明確:
// deprecated app.set("proxyConfig", {cacheMsg: true}); app.set("remoteConfig", {cacheMsg: true});
//recommended app.set("proxyConfig", {bufferMsg: true}); app.set("remoteConfig", {bufferMsg: true});
這些改名對以前的代碼保持兼容。