笔记来自:https://github.com/NetEase/pomelo/wiki/Home-in-Chinese
1、起步
1.1、欢迎使用pomelo
pomelo是一个游戏服务器框架,与以往单进程的游戏框架不同, 它是高性能、高可伸缩、分布式多进程的游戏服务器框架。
pomelo包含:框架、库、工具、客户端库、demo。
pomelo优势
- 架构的可伸缩性好
- 易用
- 框架的松耦合和可扩展性好
- 完整的demo和文档
pomelo的定位
pomelo是一个轻量级的服务器框架,它最适合的应用领域是网页游戏、社交游戏、移动游戏的服务端,开发者会发现pomelo可以用如此少的代码达到强大的扩展性和伸缩性。当然还不仅仅是游戏,用pomelo开发高实时web应用也如此合适,而且伸缩性比其它框架好。不推荐将pomelo用于大型的MMORPG游戏开发,尤其是大型3D游戏,还是需要象Bigworld这样的商用引擎来支撑。
1.2、安装pomelo
git clone https://github.com/NetEase/pomelo.git
$ cd pomelo
$ npm install
1.3、pomelo的HelloWorld
新建项目
$ mkdir HelloWorld
$ cd HelloWorld
$ pomelo init
$ sh npm-install.sh //安装依赖包
项目目录结构
game-server:是用pomelo框架搭建的游戏服务器,以文件app.js作为入口,运行游戏的所有逻辑和功能。
- app子目录:放置所有的游戏服务器代码的地方。
- config子目录:game-server下config包括了游戏服务器的所有配置信息。
- logs子目录:存放了游戏服务器所有的日志信息。
shared:存放一些前后端、game-server与web-server共用代码。
web-server:是用express框架搭建的web服务器,以文件app.js作为入口,当然开发者可以选择Nginx等其他web服务器。
启动项目
必须启动game-server(游戏服务器)和web-server(web服务器)。
$ cd game-server
$ pomelo start
$ cd web-server
$ node app
查看服务器
可以使用pomelo list查看已经启动的服务器。
服务器状态可以查看5种状态信息:
serverId:服务器的serverId,同config配置表中的id。
serverType:服务器的serverType,同config配置表中的type。
pid:服务器对应的进程pid。
headUsed:该服务器已经使用的堆大小(单位:兆)。
uptime:该服务器启动时长(单位:分钟)。
2、概述
2.1、设计动机
pomelo最初的设计初衷是为了游戏服务器, 不过在设计、开发完成后发现pomelo是个通用的分布式实时应用开发框架。
游戏服务器本质上它只是基于长连接的socket服务器。
游戏服务器的特点
复杂的socket服务器
长连接和实时响应
分区策略与负载均衡
可伸缩性与分布式开发
开发难点
a 实时性保证
--->a1 实时Tick:实时游戏的服务端一般都需要一个定时tick来执行定时任务,为了游戏的实时性,一般要求这个tick时间在100ms之内。
--->a2 广播:由于玩家在游戏里的行动要实时地通知场景中的其它玩家,必须通过广播的模式实时发送。
b 分布式开发
--->b1 多进程(服务器)的管理
--->b2 rpc调用:RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
--->b3 分布式事务、异步化操作
--->b4 负载均衡、高可用:对于有状态的服务器,要做高可用会非常困难, 但也不是完全没有办法,常见的两招:
------>b41 将状态引出到外存:例如redis, 这样进程本身就可以无状态了。但由于所有的操作都通过redis可能带来性能损耗,有些场景是不能承受这些损耗的。
------>b42 通过进程互备
原生socket开发的问题
抽象程度
可伸缩性
服务端的监控管理
游戏服务器框架也承担了应用服务器的功能,可以把框架看成容器,只要把符合容器标准的代码扔进去,容器就运行起来了。同时,它自然具备了抽象能力、可伸缩性和监控、管理等能力。
2.2、pomelo框架概述
【图】一个典型的多进程MMO运行框架
【图】pomelo的框架
下面对架构图的一些说明:
server management
pomelo是个真正多进程、分布式的游戏服务器。因此各游戏server(进程)的管理是pomelo很重要的部分,框架通过抽象使服务器的管理非常容易。server management部分维护服务器的监控信息,对服务器进行管理等功能;
network
pomelo中的通信,包括服务器与客户端的通信,也包括服务器群中各个服务器进程之间的通信,也就是服务器间的rpc调用。请求、响应、广播、rpc、session管理等构成了整个游戏框架的脉络,所有游戏流程都构建在这个脉络上。
application
应用的定义、component管理、上下文配置,这些使pomelo framework的对外接口很简单, 并且具有松耦合、可插拔架构。
pomelo的架构设计目标
- 服务器(进程)的抽象与扩展
- 客户端的请求、响应、广播
- 服务器间的通讯、调用
- 松耦合、可插拔的应用架构
服务器(进程)的抽象与扩展介绍
服务器的抽象与分类
该架构把游戏服务器做了抽象,抽象成为两类:前端服务器和后端服务器,如图:
前端服务器(frontend)的职责:
负责承载客户端请求的连接
维护session信息
把请求转发到后端
把后端需要广播的消息或响应发送到客户端
后端服务器(backend)的职责:
处理业务逻辑, 包括RPC和前端请求的逻辑
把消息推送回前端或者将对客户端请求的响应发送到前端服务器
服务器的鸭子类型
动态语言的面向对象有个基本概念叫鸭子类型。服务器的抽象也同样可以比喻为鸭子,服务器的对外接口只有两类,一类是接收客户端的请求,叫做handler,一类是接收RPC请求,叫做remote, handler和remote的行为决定了服务器长什么样子。因此我们只要定义好handler和remote两类的行为,就可以确定这个服务器的类型。
服务器抽象的实现
利用目录结构与服务器对应的形式, 可以快速实现服务器的抽象。
图中的connector,area,chat三个目录代表三类服务器类型, 每个目录下的handler与remote决定了这个服务器的行为(对外接口)。 开发者只要往handler与remote目录填代码, 就可以实现某一类的服务器。这让服务器实现起来非常方便。让服务器动起来, 只要填一份配置文件servers.json就可以让服务器快速动起来。配置文件内容示例如下:
{ "development":{ "connector": [ {"id": "connector-server-1", "host": "127.0.0.1", "port": 3150, "clientPort":3010, "frontend":true}, {"id": "connector-server-2", "host": "127.0.0.1", "port": 3151, "clientPort":3011, "frontend":true} ], "area": [ {"id": "area-server-1", "host": "127.0.0.1", "port": 3250, "area": 1}, {"id": "area-server-2", "host": "127.0.0.1", "port": 3251, "area": 2}, {"id": "area-server-3", "host": "127.0.0.1", "port": 3252, "area": 3} ], "chat":[ {"id":"chat-server-1","host":"127.0.0.1","port":3450} ] } }
所有的web应用框架都实现了请求与响应的抽象。尽管游戏应用是基于长连接的, 但请求与响应的抽象跟web应用很类似。下图的代码是一个request请求示例:
请求的api与web应用的ajax请求很象,基于convention over configuration的原则,请求不需要任何配置。如下图所示,请求的route字符串:chat.chatHandler.send, 它可以将请求分发到chat服务器上chatHandler文件定义的send方法。
pomelo的框架里还实现了对request的filter机制,广播/组播机制,以及Channel的支持等,更详细的内容可以参考后面的开发指南部分的相关内容。
服务器间rpc调用的抽象介绍
架构中各服务器之间的通讯主要是通过底层rpc框架来完成的,该rpc框架主要解决了进程间消息的路由和rpc底层通讯协议的选择两个问题。 服务器间的rpc调用也实现了零配置。实例如下图所示:
上图的remote目录里定义了一个rpc接口:chatRemote.js,它的接口定义如下:
chatRemote.kick = function(uid, player, cb) { }
其它服务器(RPC客户端)只要通过以下接口就可以实现rpc调用:
app.rpc.chat.chatRemote.kick(session, uid, player, function(data){ });
这个调用会根据特定的路由规则转发到特定的服务器。(如场景服务的请求会根据玩家在哪个场景直接转发到对应的server)。rpc框架目前在底层采用socket.io作为通讯协议,但协议对上层是透明的,以后可以替换成任意的协议。
可插拔的component扩展架构
component是pomelo的核心,pomelo的核心功能都是由component完成,开发者可定制自己的component,并加载到框架中,以完成其功能。component在开发指南部分将有更深入的讨论。以下是component的生命周期图:
用户只要实现component相关的接口:start, afterStart, stop, 就可以加载自定义的组件:
app.load([name], comp, [opts])
2.3、工具和库介绍
工具和库涵盖全面,有管理控制工具,有用来做压力测试的工具,也有一些比较通用的库。
可以帮助开发者更便捷、更有效地进行应用开发,包括创建项目、启动应用、停止应用、关闭应用等等。
一个pomelo服务器群的管理客户端,通过连接注册到master服务器,可以对服务器群进行较为高级的管理,如运行时动态的添加关闭服务器,查看服务器的状态等等。
一个用来对pomelo游戏框架进行性能测试的工具,可以帮助开发者做一些压力测试。
一个daemon服务,可以用这个服务来进行分布式部署以及日志收集。
基于pomelo-admin【https://github.com/NetEase/pomelo-admin】开发的web端监控的模块,可以通过web端的方式来对游戏服务器集群的运行状态,性能,日志等进行实时的监控。
用来管理游戏进程中需要持久化的数据在内存与存储系统之间同步的。
是对google protobuf的一个实现,借助javascript的语言特性,实现了类.proto文件的运行时解析,并用在pomelo框架中,完成对要传输消息的压缩。protobuf不仅可以用在服务端,也同样可以用于web客户端。
2.4、客户端支持介绍
pomelo的通信协议是开放的,又是可定制的,因此,理论上pomelo可以与使用任意协议的任意平台的客户端进行通信。当用户开发客户端时,可以根据相应的通信协议完成与服务端的通信。
为了方便开发者,目前pomelo提供了一些常见客户端平台的开发库。这些平台包括web,iOS,java & android,unity3d,flash以及C语言的库libpomelo等。基本上每种平台都提供了基于socket.io和使用socket/websocket的开发库版本。也欢迎大家提供一些客户端开发库,供大家使用。
详见:这里
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative
Commons BY-NC-ND 3.0
- 最后修改时间:2014年06月24日 00:45
pomelo【1】起步、概述