gate服务器

一个应用的gate服务器,一般不参与rpc调用,也就是说其配置项里可以没有port字段,仅仅有clientPort字段,它的作用是做前端的负载均衡。客户端往往首先向gate服务器发出请求,gate会给客户端分配具体的connector服务器。具体的分配策略一般是根据客户端的某一个key做hash得到connector的id,这样就可以实现各个connector服务器的负载均衡。

connector服务器

connector服务器接收客户端的连接请求,创建与客户端的连接,维护客户端的session信息。同时,接收客户端对后端服务器的请求,按照用户配置的路由策略,将请求路由给具体的后端服务器。当后端服务器处理完请求或者需要给客户端推送消息的时候,connector服务器同样会扮演一个中间角色,完成对客户端的消息发送。connector服务器会同时拥有clientPort和port,其中clientPort用来监听客户端的连接,port端口用来给后端提供服务。

应用逻辑服务器

gate服务器和connector服务器又都被称作前端服务器,应用逻辑服务器是后端服务器,它完成实际的应用逻辑,提供服务给客户端,当然客户端的请求是通过前端服务器路由过来的。后端服务器之间也会通过rpc调用而有相互之间的交互。由于后端服务器不会跟客户端直接有连接,因此后端服务器只需监听它提供服务的端口即可。

master服务器

master服务器加载配置文件,通过读取配置文件,启动所配置的服务器集群,并对所有服务器进行管理。

rpc调用

pomelo中使用rpc调用进行进程间通信,在pomelo中rpc调用分为两大类,使用namespace进行区分,namespace为sys的为系统rpc调用,它对用户来说是透明的,目前pomelo中系统rpc调用有:

  • 后端服务器向前端服务器请求session信息
  • 后端服务器通过channel推送消息时对前端服务器发起的rpc调用
  • 前端服务器将用户请求路由给后端服务器时也是sys rpc调用 除了系统rpc调用外,其余的由用户自定义的rpc调用属于user namespace的rpc调用,需要用户自己完成rpc服务端remote的handle代码,并由rpc客户端显式地发起调用

route,router

route用来标识一个具体服务或者客户端接受服务端推送消息的位置,对服务端来说,其形式一般是..,例如"chat.chatHandler.send", chat就是服务器类型,chatHandler是chat服务器中定义的一个Handler,send则为这个Handler中的一个handle方法。对客户端来说,其路由一般形式为onXXX,当服务端推送消息时,客户端会有相应的回调。 一般来说具体的同类型应用服务器都会有多个,当客户端请求到达后,前端服务器会将用户客户端请求派发到后端服务器,这种派发需要一个路由函数router,可以粗略地认为router就是根据用户的session以及其请求内容,做一些运算后,将其映射到一个具体的应用服务器id。可以通过application的route调用给某一类型的服务器配置其router。如果不配置的话,pomelo框架会使用一个默认的router。pomelo默认的路由函数是使用session里面的uid字段,计算uid字段的crc32校验码,然后用这个校验码作为key,跟同类应用服务器数目取余,得到要路由到的服务器编号。注意这里有一个陷阱,就是如果session没有绑定uid的话,此时uid字段为undefined,可能会造成所有的请求都路由到同一台服务器。所以在实际开发中还是需要自己来配置router。

Session, FrontendSession, BackendSession, SessionService, BackendSessionService

在pomelo框架中,有这三个session的概念,同时又有两个service: SessionServiceBackendSessionService,也是最令人迷惑的地方,这里尝试给出一些说明,让你的理解更清晰一些: Session的是一个客户端连接的抽象,它的大致字段如下:

{
id : <session id> // readonly
frontendId : <frontend server id> // readonly
uid : <bound uid> // readonly
settings : <key-value map> // read and write
__socket__ : <raw_socket>
__state__ : <session state> // ...
}
  • id是这个session的id,是全局唯一的,一般使用自增的方式来生成;
  • frontendId是维护这个session的前端服务器的id;
  • uid是这个session所绑定的用户id;
  • __socket__是底层原生socket的引用;
  • __state__用来指明当前session的生命周期状态。
  • settings维护一个key-value map,用来描述session的一些自定义属性,比如聊天应用中的房间号就可以看作是session的一个自定义属性。

从上面的分析看,一个session一旦建立,那么id, frontendId,__socket__, __state__, uid都是确定的,都应该是只可读不可写的。而settings也不应该被随意的修改。 因此,在前端服务器中,引入了FrontendSession, 可以把它看作是一个内部session在前端服务器中的傀儡,FrontendSession的字段大致如下:

{
id : <session id> // readonly
frontendId : <frontend server id> // readonly
uid : <bound uid> // readonly
settings : <key-value map> // read and write
}

其作用:

  • 通过FrontendSession可以对settings字段进行设置值,然后通过调用FrontendSession的push方法,将设置的settings的值同步到原始session中;
  • 通过FrontendSession的bind调用,还可以给session绑定uid;
  • 当然也可以通过FrontendSession访问session的只读字段,不过对FrontendSession中与session中相同的只读字段的修改并不会反映到原始的session中。

SessionService维护所有的原始的session信息,包括不可访问的字段,绑定的uid以及用户自定义的字段。

下面再说BackendSession,与FrontendSession类似,BackendSession是用于后端服务器的,可以看作是原始session的代理,其数据字段跟FrontendSession基本一致。

BackendSession是由BackendSessionService创建并维护的,在后端服务器接收到请求后,由BackendSessionService根据前端服务器rpc的参数,进行创建。对BackendSessionService的每一次方法调用实际上都会生成一个远程调用,比如通过一个sid获取其BackendSession。同样,对于BackendSession中字段的修改也不会反映到原始的session中,不过与FrontendSession一样,BackendSession也有push,bind,unbind调用,它们的作用与FrontendSession的一样,都是用来修改原始session中的settings字段或者绑定/解绑uid的,不同的是BackendSession的这些调用实际上都是名字空间为sys的远程调用。

Channel

channel可以看作是一个玩家id的容器,主要用于需要广播推送消息的场景。可以把某个玩家加入到一个Channel中,当对这个Channel推送消息的时候,所有加入到这个Channel的玩家都会收到推送过来的消息。一个玩家的id可能会被加入到多个Channel中,这样玩家就会收到其加入的Channel推送过来的消息。需要注意的是Channel都是服务器本地的,应用服务器A和B并不会共享Channel,也就是说在服务器A上创建的Channel,只能由服务器A才能给它推送消息。

request, response, notify, push

pomelo中有四种消息类型的消息,分别是request,response,notify和push,客户端发起request到服务器端,服务器端处理后会给其返回响应response;notify是客户端发给服务端的通知,也就是不需要服务端给予回复的请求;push是服务端主动给客户端推送消息的类型。在后面的叙述中,将会使用这些术语而不再作解释。

filter

filter分为before和after两类,每类filter都可以注册多个,形成一个filter链,所有的客户端请求都会经过filter链进行一些处理。before filter会对请求做一些前置处理,如:检查当前玩家是否已登录,打印统计日志等。after filter是进行请求后置处理的地方,如:释放请求上下文的资源,记录请求总耗时等。after filter中不应该再出现修改响应内容的代码,因为在进入after filter前响应就已经被发送给客户端。

handler

handler是实现具体业务逻辑的地方,在请求处理流程中,它位于before filter和after filter之间,handler的接口声明如下:

handler.methodName = function(msg, session, next) {
// ...
}

参数含义与before filter类似。handler处理完毕后,如有需要返回给客户端的响应,可以将返回结果封装成js对象,通过next传递给后面流程。

error handler

error handler是一个处理全局异常的地方,可以在error handler中对处理流程中发生的异常进行集中处理,如:统计错误信息,组织异常响应结果等。error handler函数是可选的,如果需要可以通过

app.set('errorHandler', handleFunc);

来向pomelo框架进行注册,函数声明如下:

errorHandler = function(err, msg, resp, session, next) {
// ...
}

其中,err是前面流程中发生的异常;resp是前面流程传递过来,需要返回给客户端的响应信息。其他参数与前面的handler一样。

component

pomelo 框架是由一些松散耦合的component组成的,每个component完成一些功能。整个pomelo框架可以看作是一个component容器,完成component的加载以及生命周期管理。pomelo的核心功能都是由component完成的,每个component往往有start,afterStart,stop等调用,用来完成生命周期管理。

admin client, monitor, master

在对pomelo服务器进行管理的时候,有三个概念admin client, monitor, master。

  • monitor运行在各个应用服务器中,它会向master注册自己,向master上报其服务器的信息,当服务器群有变化时,接收master推送来的变化消息,更新其服务器上下文。

  • master运行在应用服务器中,它会收集整个服务器群的信息,有变化时会将变化推送到各个monitor;同时,master还接受admin client的请求,按照client发出的命令,执行对应的操作,如查询整个服务器群的状态,增加一个服务器等。

  • client独立运行自己的进程,它会发起到master的连接,然后通过对master发出请求或者命令,来管理整个服务器群。目前工具pomleo-cli就是这样的一个客户端。

admin module

在pomelo中,module特指服务器监控管理模块,与component类似,不过在module中实现的是监控逻辑,比如收集进程状态等。用户在使用时,可以通过applicationregisterAdmin注册管理模块,实现用户自己定制的监控管理功能。每一个module中都会定义下面四种回调函数,不过都是可选的:

  • masterHandler(agnet, msg, cb) 当有应用服务器给master发监控数据时,这个回调函数会由master进程进行回调,完成应用服务器的消息处理;
  • monitorHandler(agent, msg, cb) 当有master请求应用服务器的一些监控信息时,由应用服务器进行回调,完成对master请求的处理;
  • clientHandler(agent, msg, cb)当由管理客户端向master请求服务器群信息时,由master进程进行回调处理客户端的请求。
  • start(cb) 当admin module,注册加载完成后,这个回调会被执行,在这里可以做一些初始化工作。

plugin

plugin是pomelo 0.6加入的全新的扩展机制,一个plugin由多个component以及一些事件响应处理器组成。它提供了一种很灵活的机制来扩展pomelo。不仅可以提供component的功能,还可以对整个框架的全局事件作出响应处理。

pomelo 服务器开发常用术语的更多相关文章

  1. 学习游戏服务器开发必看,C++游戏服务器开发常用工具介绍

    C++游戏服务器开发常用工具介绍 在软件开发过程中需要使用的工具类型实属众多,从需求建模到软件测试,从代码编译到工程管理,这些工具都对项目有着不可替代的作用.庄子有云,"吾生也有涯,而知也无 ...

  2. Linux 服务器开发常用命令操作

    1)查看网络端口 netstat -na --ip 2)查看特定应用程序进程 ps -ef | grep vsftp  or ps aux | grep xxx.exe 3)查看系统日志 vi /et ...

  3. Hacker(七)----黑客常用术语和DOS命令

    掌握基本的黑客术语和DOS命令是一名黑客最基本的技能,黑客术语能够实现自己和其他人之间的正常交流.DOS命令就是DOS操作系统的命令,它是一种面向磁盘的操作命令.黑客在入侵目标主机的过程中经常会使用这 ...

  4. C++服务器开发之笔记三

    为什么需要原子性操作? 我们考虑一个例子:(1)x++这个常见的运算符在内存中是怎样操作的?从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址 若是有两个线程同时对同一个变量++, ...

  5. OLE/COM 对象查看器 & OLE常用术语

    "OLE/COM Object Viewer"(OLE/COM 对象查看器)查看你系统上安装的所有 COM 对象时,是一个非常便利的工具. 它是 Windows 2000 资源套件 ...

  6. Centos环境下部署游戏服务器-常用命令

         图1     在Linux的世界,如果你不玩命令,那你见了同行都不好意思和人家打招呼.同时服务器正常状况下放在远端,一般都是开ssh登录服务器,相信远程桌面的人很少见吧.这篇文章说说Linu ...

  7. J2EE开发常用开源框架技术(转)

    主要就我所了解的J2EE开发的框架或开源项目做个介绍,可以根据需求选用适当的开源组件进行开发.主要还是以Spring为核心,也总结了一些以前web开发常用的开源工具和开源类库 1持久层:1)Hiber ...

  8. C#(Net)软件开发常用工具汇总,提高你的开发效率

    C#(Net)软件开发常用工具汇总,提高你的开发效率 写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用技术文章. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是 ...

  9. linux下http服务器开发

    linux下http服务器开发 1.mystery引入 1)超文本传输协议(HTTP)是一种应用于分布式.合作式.多媒体信息系统的应用层协议 2)工作原理 1)客户端一台客户机与服务器建立连接后,会发 ...

随机推荐

  1. CSS基础深入之细说盒子模型

    Html任何一个元素(element)都可以当成一个盒子(box)来看待,可以结合现实中的盒子来理解下文,下文其中一些单词应该是通俗易懂的需要记录的单词. 基本情况 每一个盒子都有一个内容区域(con ...

  2. 【 D3.js 进阶系列 】 进阶总结

    进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...

  3. Application Pool Identities

    Whether you are running your site on your own server or in the cloud, security must be at the top of ...

  4. JS中图片的放大缩小没反应

    这段代码无反应: 代码如下: <script type="text/javascript"> onload = function () { document.getEl ...

  5. MySQL SQL优化之字符串索引隐式转换

    之前有用户很不解:SQL语句非常简单,就是select * from test_1 where user_id=1 这种类型,而且user_id上已经建立索引了,怎么还是查询很慢? test_1的表结 ...

  6. [转]ubuntu zip 文件乱码解决 压缩乱码

    ubuntu zip 文件乱码解决 压缩乱码 1.1 通过unzip行命令解压,指定字符集 unzip -O CP936 xxx.zip (用GBK, GB18030也可以) 有趣的是unzip的ma ...

  7. Kooboo CMS的安装步骤

    Kooboo CMS的安装步骤 来自Kooboo document 跳转到: 导航, 搜索 http://www.microsoft.com/web/gallery/install.aspx?appi ...

  8. android xml文件

    一.布局文件:在layout目录下,使用比较广泛: 我们可以为应用定义两套或多套布局,例如:可以新建目录layout_land(代表手机横屏布局),layout_port(代表手机竖屏布局),系统会根 ...

  9. Oracle函数:求两个数的最小公倍数

    CREATE or replace function GetGbs(num1 NUMBER,num2 NUMBER) RETURN NUMBER is resultnum NUMBER; maxnum ...

  10. Java内存结构、类的初始化、及对象构造过程

    概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的 ...