pomelo架构概览

pomelo之所以简单易用、功能全面,并且具有高可扩展性、可伸缩性等特点,这与它的技术选型和方案设计是密不可分的。在研究大量游戏引擎设计思路基础上,结合以往游戏开发的经验,确定了pomelo框架的设计方案。

pomelo为什么采用node.js开发?

node.js自身特点与游戏服务器的特性惊人的吻合。 在node.js的官方定义中, fast、scalable、realtime、network这几个特性都非常符合游戏服务器的要求。游戏服务器是个网络密集型的应用,对实时性要求极高,而node.js在网络io上的优势也完全可以满足这点。使用node.js开发游戏服务器的优势总结:

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

游戏服务器的运行架构

一个真正高可扩展的游戏运行架构必须是多进程的。google的gritsgame, mozilla的browserquest 都采用了node.js作为游戏服务器开发语言, 但它们都采用了单进程的node.js服务器,缺乏扩展性,这使它们可以支撑的在线用户数量是很有限的(这两个游戏主要是作为HTML5游戏的demo)。而多进程的架构可以很好的实现游戏服务器的的扩展性,达到支撑较多在线用户、降低服务器压力等要求。

一个典型的多进程MMO运行架构, 如下图所示:

说明: 上图中的方块表示进程, 定义上等同于“服务器“

运行架构说明:

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

游戏运行架构与web应用运行架构的区别

该游戏运行架构表面上看与web应用运行架构很类似,connector类似于web应用的apache/nginx等web服务器,后端的服务器群类似于web应用中的应用服务器(如tomcat),但实际上存在着很大的差别:

  • 长连接与短连接。web应用使用基于http的短连接以达到最大的可扩展性,游戏应用采用基于socket(websocket)的长连接,以达到最大的实时性。
  • 分区策略不同。web应用的分区可以根据负载均衡自由决定, 而游戏则是基于场景(area)的分区模式, 这使同场景的玩家跑在一个进程内, 以达到最少的跨进程调用。
  • 有状态和无状态。web应用是无状态的, 可以达到无限的扩展。 而游戏应用则是有状态的, 由于基于场景的分区策略,它的请求必须路由到指定的服务器, 这也使游戏达不到web应用同样的可扩展性。
  • 广播模式和request/response模式。web应用采用了基于request/response的请求响应模式。而游戏应用则更频繁地使用广播, 由于玩家在游戏里的行动要实时地通知场景中的其它玩家, 必须通过广播的模式实时发送。这也使游戏在网络通信上的要求高于web应用。

如此复杂的运行架构, 我们需要一个框架来简化开发

游戏的运行架构很复杂,要想支撑起如此复杂的运行架构,必须要有一个框架来简化开发。
pomelo正是这样一个框架,它使我们用最少的代码, 最清晰的结构来实现复杂的运行架构。

pomelo的框架介绍

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

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

pomelo的架构设计目标

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

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

  • 客户端的请求、响应、广播

客户端的请求、响应与web应用是类似的, 但框架是基于长连接的, 实现模式与http请求有一定差别。
广播是游戏服务器最频繁的操作, 需要方便的API, 并且在性能上达到极致。

  • 服务器间的通讯、调用

尽管框架尽量避免跨进程调用,但进程间的通讯是不可避免的, 因此需要一个方便好用的RPC框架来支撑。

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

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

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

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

服务器的抽象与分类

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

前端服务器(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的生命周期图:

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

app.load([name], comp, [opts])

总结

上面的应用框架构成了pomelo framework的基础。在此基础上,配合pomelo提供的游戏开发库和相关工具集,开发游戏服务器将变得非常方便。 后面的tutorial将带我们进入开发游戏应用的实际案例。

pomelo架构概览相关推荐

  1. flutter ios启动白屏_Flutter技术架构概览

    前言 最近在整理各种技术架构,给自己的列了个TODO list,希望能在几个月的时间内,研究完各种前端技术架构,包括移动端技术架构.今天分享一下自己整理的flutter技术架构.完整的技术架构TODO ...

  2. Apache Beam的架构概览

    不多说,直接上干货! Apache Beam是一个开源的数据处理编程库,由Google贡献给Apache的项目,前不久刚刚成为Apache TLP项目.它提供了一个高级的.统一的编程模型,允许我们通过 ...

  3. python前端用什么架构_Python web世界观——web架构概览(适合传统软件工程师)...

    Python web世界观--web架构概览(适合传统程序员) 传统web server面临的问题 我们知道传统的web server,一个进程打开socket,监听,来了请求生成新的进程(或线程.或 ...

  4. KubeFed 集群联邦的演进和架构概览

    KubeFed 集群联邦的演进和架构概览 Kubernetes 集群联邦 Kubernetes 从 1.8 版本起就声称单集群最多可支持 5000 个节点和 15 万个 Pod,我相信很少有公司会部署 ...

  5. Hyperledger Fabric1.0架构概览

    Hyperledger是被业界非常看到的联盟链的实现,包括IBM.Intel.R3.各个大型商业银行等都参与其中,带给我们关于区块链技术与软件工业.金融.保险.物流等领域碰撞结合的想象空间:在这个联盟 ...

  6. Wine 开发者指导/架构概览

    1 Wine的概览 1.1 前言 Wine常常被看做一个缩写,代表"Wine Is Not an Emulator".有时它也被称为"Windows模拟器".从 ...

  7. 图解USB标准之架构概览

    前面写了一些SPI/I2C/RS-485之类的文章,有朋友留言希望能分享一些USB方面的梳理总结,今天就从系统标准层面先来梳理一下.看看有没有朋友喜欢.先从系统层面来梳理.个人学习,习惯于先从整体上摸 ...

  8. 一元夺宝系统整体架构概览

      系统介绍 一元夺宝项目,前段时间非常火:出现了很多夺宝平台,最近由于市场的监管,确实少了很多:夺宝模式其实非常简单,类似于彩票:就跟有个段子说的:大家每人给我发10元,每满50元将抽出一名幸运用户 ...

  9. CockroachDB架构——概览

    CockroachDB被设计用于创建开发者想用的源码可用的数据:集扩展性与一致性一体的数据库.开发者经常问到我们是如何实现的,该指南详细说明了CockroachDB进程的内部工作原理. 然而,使用Co ...

最新文章

  1. 进程状态控制-进程创建
  2. MariaDB三种方法安装及多实例实现
  3. Hibernate一对多单向关联和双向关联映射方法及其优缺点
  4. vue-router 按需加载
  5. restTemplate踩过的坑-spring clound--cloud内部服务调用重试次数
  6. leetcode979. 在二叉树中分配硬币(dfs)
  7. linux树莓派扩容,树莓派ubuntu 扩容
  8. linux 内核块设备驱动,linux之块设备驱动
  9. 用 python 画散点图与气泡图
  10. rhino编程语言c井,Rhino插件开发:RhinoScript脚本教程(4):VBScript基础
  11. 如何将excel文件联系人转换成vcf文件
  12. 互联网原创表情论坛举行 探索设计师盈利新生态
  13. mysql实验数据库报告_MySQL数据库技术》实验报告模板
  14. WPS Office V15.3.2绿化版免费下载
  15. FPGA图像处理 —— fpga实现cameralink接口图像传输
  16. svn和git版本管理
  17. Markdown基本语法
  18. Windows2012 系统从MBR转GPT免重装的经验
  19. HBO宣布续订《西部世界》第三季
  20. 【软件测试】快速入行软件测试

热门文章

  1. lua table操作函数
  2. [文摘20071019]九九重阳节的来历 重阳节传说故事 重阳节的活动习俗 重阳节诗篇...
  3. 以太网口差分电平_TTL和差分电平
  4. IntelliJ IDEA - 闪退解决方案
  5. 7-30 实验3_13_最大公约数和最小公倍数 (100 分)
  6. 苹果手机怎么恢复丢失的数据?果粉必看!
  7. 解决 ES6 Module 报 Access to script at ‘xx‘ from origin ‘null‘ has been blocked by CORS policy
  8. vue获取当前的月份_vue根据选择的月份动态展示当前月份的每一天并展示每一天所对应的星期几...
  9. IDL 中将数组中大于或者小于某一值的数值变成一个定值,其他值不变
  10. 华硕笔记本台式机安装系统