pomelo简介

Pomelo简介

Node扫盲

什么是nodejs

Node.js是一个基于Chrome JavaScript运行时建立的平台,用于方便地搭建响应速度快、易于扩展的网络应用。本来,js是运行于浏览器端的语言,例如google浏览器chrome,该浏览器执行js的引擎,即解释器,叫做V8V8 Javascript引擎采用C++编写,开源,可嵌入到其他应用程序中,正是由于这一特点,才催生了node

Nodejs就以V8为基础,创建了一个新的javascript运行时环境,叫做node(我们写一个helloworld.jscmd中,node helloworld.js 就可以运行。类似于java helloworld.class 只是省去了javac的编译,因为js本身是解释执行,不生产目标程序)Node本身是一个javascript解释器,更确切地说,是服务器端的javascript运行时环境,它扩充了浏览器端的javascript运行时环境,开放了一些文件系统和系统命令接口,提供了net,socket编程的api。所有我们可以用node轻松地写出一个http服务器,如下:

Cmd中执行改node程序

以上就是一个相对完整的http服务器,访问端口返回HelloWorld

NodeJS的作者说,他创造NodeJS的目的是为了实现高性能Web服务器,他首先看重的是事件机制和异步IO模型的优越性,而不是JS。但是他需要选择一种编程语言实现他的想法,这种编程语言不能自带IO功能,并且需要能良好支持事件机制。JS没有自带IO功能,天生就用于处理浏览器中的DOM事件,并且拥有一大群程序员,因此就成为了天然的选择。

Node的重要特性

Nodejs最重要的特性是事件驱动和非阻塞IO。举个例子

到餐厅点餐,点完餐后拿到了一个号码,拿到号码,我们往往会在位置上等待,而在我们后面点餐的请求会继续得到处理,同样是拿了一个号码然后到一旁等待,接待员能一直进行处理。等到饭菜做号了,会喊号码,我们拿到了自己的饭菜,进行后续的处理(吃饭)。这个喊号码的动作在NodeJS中叫做回调(Callback),能在事件(烧菜,I/O)处理完成后继续执行后面的逻辑(吃饭),这体现了NodeJS的显著特点,异步机制、事件驱动整个过程没有阻塞新用户的连接(点餐),也不需要维护已经点餐的用户与厨师的连接。

基于这样的机制,理论上陆续有用户请求连接,NodeJS都可以进行响应,因此NodeJS能支持比JavaPHP程序更高的并发量虽然维护事件队列也需要成本,再由于NodeJS是单线程,事件队列越长,得到响应的时间就越长,并发量上去还是会力不从心。

总结一下NodeJS是怎么解决并发连接这个问题的:更改连接到服务器的方式,每个连接发射(emit)一个在NodeJS引擎进程中运行的事件(Event),放进事件队列当中,而不是为每个连接生成一个新的OS线程(并为其分配一些配套内存),javaphp对每一个请求都是分配一个连接,主要表现在系统资源上,例如内存。

捕鱼服务端在发挥node的异步特性上,做得并不是很多,大部分操作,因为逻辑要求,都被写成了同步操作。

Nodejs优缺点

优点:    1. 高并发(最重要的优点)

2. 适合I/O密集型应用

缺点:    1. 不适合CPU密集型应用;CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;

解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;

2. 只支持单核CPU,不能充分利用CPU

3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

原因:单进程,单线程

解决方案:(1Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;

2)开多个进程监听同一个端口,使用cluster模块;

4. 开源组件库质量参差不齐,更新快,向下不兼容

5. Debug不方便,错误没有stack trace

 

以下内容在Pomelo(Homein Chinese)均可找到,这里挑选一些概要章节,做一个简介

Pomelo起源

Pomelo是网易开发的一个Nodejs游戏开源框架。以下是pomelo开源框架负责人的自述

2011年下半年开始,我们在游戏开发上有了些积累,希望在游戏服务器上有更前沿的研究,在技术选型时我们比较了erlang, node.jsjava等多种语言,发现node很适合做开发游戏服务器,它的事件IO模型与单线程应用模型跟游戏服务器简直是绝配。于是在201111月,我们正式立项并取名项目为pomelo

项目的开发经历了原型、框架开发、demo开发,性能优化,不断重构、调优、整理等几个阶段。

我们的原型开发只经历了一个月, 当时做了个很简单的捡宝游戏; 框架的抽取和开发是项目最难的阶段, 要定义抽象出框架模型很难, 而且我们是多进程的应用框架完全没有蓝本参考,到了20124月终于完成了框架雏形;之后的demo开发比较快,我们用了一个半月时间就搭建了一个HTML5客户端的网页版的MMORPG并在6月底的node party上小试牛刀了一把;然后我们用了两个月时间做压力测试和性能调优,做了一些性能优化的工具,并把遇到的性能瓶颈都解决了;到了9月之后我们的主要工作就是重构、文档,不断地优化接口,并在1120日左右开源我们的框架。

2012年底开源的pomelo,目前的商用成功案例已经很多,如中国平安在线客服系统,网易消息推送平台,还有一系列扑克麻将游戏。。。在成功案例有参考。

 

Pomelo设计动机

pomelo本身的设计理念

1. 第一个理念是让游戏(高实时web应用)服务器的开发变得非常简单,而不是解决某类算法或系统上的难题。

2.第二个理念是重视性能和可伸缩性,用户用pomelo开发出来的游戏天生具有很强的伸缩性,扩展也很容易。pomelo在性能优化上也花了很多功夫,并且会持续进行。

3.第三个理念是让第三方很容易扩展,框架用了很多插件式的设计,组件component、路由规则、甚至管理控制台都可以完全由第三方扩展。

针对目前游戏服务器框架产品市场的情况,没有适用于中小型游戏开发的框架,我们推出了pomelo框架,它是基于node.js开发的高性能、可伸缩、轻量级游戏服务器框架,使得游戏服务器的开发变得简单。与其他的类似的框架相比,它的主要优势有以下几点:

  • 开发模型快速、易上手,基于convention over configuration的原则,严格遵从已有惯例和使用合理的缺省选项,让代码达到最大的简化。
  • 架构的可伸缩性和可扩展性好,pomelo在服务器扩展和应用扩展上实现得非常方便。
  • 轻量级,虽然是分布式架构,但启动非常迅速,占用资源少。
  • 参考全面,框架不仅提供了完整的中英文档,还提供了完整的MMO demo代码(客户端使用了HTML5),可以作为很好的开发参考。

为什么选择node.js

在讲了这么多分布式开发的难点之后,引入node.js实在是太自然了,它天生的异步编程模型解决了分布式开发的很多问题:

  • 天生的分布式

node.js之所以叫node就是因为它天生就是做多进程开发的, 多个节点(node)互相通讯交织在一起组成的分布式系统是node天生就应该这么干的。它的编程模式里天生就是这种模式,两阶段提交、异步化操作这些看似复杂的工作里在node.js只是一个正常的异步执行流程。例如前面提到的分布式事务、异步化操作在node.js里只是个正常的流程。

  • 单线程的应用模型

node.js的单线程处理能力远比其它语言强大,而单线程处理游戏逻辑是最简单,最不容易出错,而且不可能出现死锁、锁竞争的情况。

  • 网络io与可伸缩性的优势

游戏是非常io密集型的应用, 采用node.js是最合适的, 可达到最好的可伸缩性。虽然有很高的可伸缩性,却并没有因此损失性能。node.js生来就是为io而生的,而游戏服务器刚好是网络密集型的应用。node.js的网络编程接口简单,抽象程度高。

  • 语言优势

使用javascript开发可以实现快速迭代。它不仅由于脚本语言的轻量、简单带来了开发效率的提升,还可以与一些类型的客户端共享部分代码,如html5unity3djs客户端等。另外,语言的动态性带来了很多框架设计的便利。

 

Pomelo框架概述

游戏服务器的运行架构

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

一些说明:

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

Pomelo框架介绍

pomelo框架的组成如图所示:

下面对架构图的一些说明:

  • server management

pomelo是个真正多进程、分布式的游戏服务器。因此各游戏server(进程)的管理是pomelo很重要的部分,框架通过抽象使服务器的管理非常容易。server management 部分维护服务器的监控信息,对服务器进行管理等功能;

  • network

pomelo中的通信,包括服务器与客户端的通信,也包括服务器群中各个服务器进程之间的通信,也就是服务器间的rpc调用。请求、响应、广播、rpcsession管理等构成了整个游戏框架的脉络,所有游戏流程都构建在这个脉络上。

  • application

应用的定义、component管理、上下文配置,这些使pomelo framework的对外接口很简单, 并且具有松耦合、可插拔架构。

Pomelo架构设计目标

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

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

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

前端服务器(frontend)的职责:

  • 负责承载客户端请求的连接
  • 维护session信息
  • 把请求转发到后端
  • 把后端需要广播的消息或响应发送到客户端

后端服务器(backend)的职责:

  • 处理业务逻辑, 包括RPC和前端请求的逻辑
  • 把消息推送回前端或者将对客户端请求的响应发送到前端服务器

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

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

请求的apiweb应用的ajax请求很象,基于convention over configuration的原则, 请求不需要任何配置。 如下图所示,请求的route字符串:chat.chatHandler.send 它可以将请求分发到chat服务器上chatHandler文件定义的send方法。

pomelo的框架里还实现了对requestfilter机制,广播/组播机制,以及Channel的支持等,更详细的内容可以参考后面的开发指南部分的相关内容。

 

服务器间的通讯、调用

尽管框架尽量避免跨进程调用,但进程间的通讯是不可避免的, 因此需要一个方便好用的rpc框架来支撑。架构中各服务器之间的通讯主要是通过底层rpc框架来完成的,该rpc框架主要解决了进程间消息的路由和rpc底层通讯协议的选择两个问题。 服务器间的rpc调用也实现了零配置。rpc框架目前在底层采用socket.io作为通讯协议,但协议对上层是透明的,以后可以替换成任意的协议。

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

应用的扩展性很重要,pomelo framework支持以component的形式插入任何第三方组件, 也支持加入自定义的路由规则, 自定义的filter,自定义admin module等。componentpomelo的核心,pomelo的核心功能都是由component完成,开发者可定制自己的component,并加载到框架中,以完成其功能。

在本部分,讲述了pomelo框架的整体架构,以及其设计目标。pomelo框架完成了对服务器的抽象,对用户请求响应以及服务器端主动推送消息的抽象,服务器间rpc调用的抽象,可插拔的components抽象。这些抽象使得pomelo非常灵活以及易于使用,易于扩展。

Pomelo与客户端交互

pomelo的通信协议是开放的,又是可定制的,因此,理论上pomelo可以与使用任意协议的任意平台的客户端进行通信。当用户开发客户端时,可以根据相应的通信协议完成与服务端的通信。

为了方便开发者,目前pomelo提供了一些常见客户端平台的开发库。这些平台包括webiOS java & android, unity3d, flash以及C语言的库libpomelo等。基本上每种平台都提供了基于socket.io和使用socket/websocket的开发库版本。也欢迎大家提供一些客户端开发库,供大家使用。

  • cocos2dx
    • c++: NetEase / pomelo-cocos2dchat

 

pomelo通讯类

目前Pomelo服务器提供两类connectorsioconnectorhybridconnector,分别对于基于socket.io和二进制的通讯。

1.1 sioconnector

支持基于socket.io的通讯协议,也是Pomelo框架默认采用的connector(主要是兼容老版本)。之前基于socket.io的服务器和客户端代码不用修改就可以使用(默认使用)。

1.2hybridconnector

支持socketwebsocket,使用二进制通讯协议,并且支持route字典压缩和protobuf压缩的connector,需要在app.js中显式配置。

Pomelo通讯方式

pomelo的客户端和服务器之间的通讯可以分为三种:

request-response

pomelo中最常用的就是request-response模式,客户端发送请求,服务器异步响应。客户端的请求发送形式类似ajax类似:pomelo.request(url, msg, function(data){});第一个参数为请求地址,完整的请求地址主要包括三个部分:服务器类型、服务端相应的文件名及对应的方法名。第二个参数是消息体,消息体为json格式,第三个参数是回调函数,请求的响应将会把结果置入这个回调函数中返回给客户端。

notify

notifyrequestresponse类似,唯一区别是客户端只负责发送消息到服务器,客户端不接收服务器的消息响应。 pomelo.notify(url, msg);

push

push则是服务器主动向客户端进行消息推送,客户端根据路由信息进行消息区分,转发到后。通常游戏服务器都会发送大量的这类广播。pomelo.on(route, function(data){});

以上是javascriptapi 其它客户端的API基本与这个类型。由于APIajax极其类似,所有web应用的开发者对此都不陌生。

你可能感兴趣的:(JavaScript,socket,nodejs,pomelo)