网易游戏服务器开发框架,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});
这些改名对以前的代码保持兼容。