pomelo 服务器框架

pomelo是由网易使在node.js基础上编写的服务器框架,其特色为简单易用、功能全面,而且具备高可扩展性、可伸缩性等。javascript

具体介绍可参考官方文档:https://github.com/NetEase/pomelo/wiki/html

如下是摘录自文档的框架的简单优点介绍:前端

使用node.js开发游戏服务器的优点总结:
   1. io与可伸缩性的优点。io密集型的应用采用node.js是最合适的, 可达到最好的可伸缩性。
   2. 多进程单线程的应用架构。node.js天生采用单线程, 使它在处理复杂逻辑的时候无需考虑线程同步、锁、死锁等一系列问题,
        减小了不少逻辑错误。由多进程node.js组成的服务器群是最理想的应用架构。
   3. 语言优点。使用javascript开发能够实现快速迭代,若是客户端使用html 5,更可实现代码共用。java

 

游戏服务器通常架构:node

运行架构说明:

  • 客户端经过websocket长链接连到connector服务器群。
  • connector负责承载链接,并把请求转发到后端的服务器群。
  • 后端的服务器群主要包括按场景分区的场景服务器(area)、聊天服务器(chat)和状态服务器等(status), 这些服务器负责各自的业务逻辑。真实的案例中还会有各类其它类型的服务器。
  • 后端服务器处理完逻辑后把结果返回给connector, 再由connector广播回给客户端。
  • master负责统一管理这些服务器,包括各服务器的启动、监控和关闭等功能。
     

    pomelo的框架介绍

    pomelo framework的组成架构如图所示:git

    pomelo框架
     

  • server management, pomelo是个真正多进程、分布式的游戏服务器。所以各游戏server(进程)的管理是pomelo很重要的部分,框架经过抽象使服务器的管理很是容易。
  • network, 请求、响应、广播、RPC、session管理等构成了整个游戏框架的脉络,全部游戏流程都构建在这个脉络上。
  • application, 应用的定义、component管理,上下文配置, 这些使pomelo framework的对外接口很简单, 而且具备松耦合、可插拔架构。
  • pomelo的架构设计目标

  • 服务器(进程)的抽象与扩展
  • 在web应用中, 每一个服务器是无状态、对等的, 开发者无需经过框架或容器来管理服务器。 但游戏应用不一样, 游戏可能须要包含多种不一样类型的服务器,每类服务器在数量上也可能有不一样的需求。这就须要框架对服务器进行抽象和解耦,支持服务器类型和数量上的扩展。github

  • 客户端的请求、响应、广播
  • 客户端的请求、响应与web应用是相似的, 但框架是基于长链接的, 实现模式与http请求有必定差异。 广播是游戏服务器最频繁的操做, 须要方便的API, 而且在性能上达到极致。web

  • 服务器间的通信、调用
  • 尽管框架尽可能避免跨进程调用,但进程间的通信是不可避免的, 所以须要一个方便好用的RPC框架来支撑。ajax

    * 松耦合、可插拔的应用架构。json

    应用的扩展性很重要, pomelo framework支持以component的形式插入任何第三方组件, 也支持加入自定义的路由规则, 自定义的filter等。

    下面分别对这三个目标进行详细的分析:

    服务器(进程)的抽象与扩展介绍

    服务器的抽象与分类

    该架构把游戏服务器作了抽象, 抽象成为两类:前端服务器和后端服务器

    前端:gate,connector     后端:各个逻辑服务器

    前端服务器(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机制,广播/组播机制,详细介绍见pomelo框架参考

    服务器间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做为通信协议,但协议对上层是透明的,之后能够替换成任意的协议。

    pomelo支持可插拔的component扩展架构

    component是pomelo自定义组件,开发者可自加载自定义的component。 component在pomelo框架参考将有更深刻的讨论。 如下是component的生命周期图:

    components

    用户只要实现component相关的接口: start, afterStart, stop, 就能够加载自定义的组件:

    app.load([name], comp, [opts])
相关文章
相关标签/搜索