技术文章 > 服务端 > pomelo 用户指南 > 框架驱动 

框架驱动


使用 pomelo 开发应用时,我们一直关注的是给框架填入相应的回调,给 app 配置一些上下文。而没有太多关心整个框架的驱动力量。 在我们启动应用的时候,我们会在 game-server 目录下执行 pomelo start,然后就能看到很多 log 信息,这样就启动了很多服务器。但是我们并没有太多关心框架是如何做到这一点的,在这部分,将试图向你讲述 pomelo 框架是如何驱动的。
首先看下图:


这张图是以 chat 为例,当 chat 应用启动后,使用命令
pstree -au
得到的进程树的一部分,我们从图上可以清楚地看出,pomelo start 调用进程会创建子进程,子进程执行的是 node app.js env=development,然后这个子进程又会创建很多子进程,这些子进程执行的跟原进程同样的文件,只是多了更多的参数,它们后面会有一些诸如id、serverType、port 等这样的参数。
好了,现在我们可以做一些简单的解释了,pomelo start 的进程直接创建的那个子进程,实际上就是我们的 master 服务器进程,而由 master 服务器创建的那些子进程,他们执行的是类似于
`node /app.js env=development id=chat-server-1 ...`
这样命令的则是由 master 服务器创建的子进程,这些子进程也就是我们的应用服务器。当然,这里的进程都在一台主机上,所以会有父子关系,也就是说 master 进程是其他应用服务器的父进程。如果各个进程分布在不同的物理主机上的话,pomelo 默认会使用 ssh 的方式远程启动相应的服务器,那样的话,master 进程与应用程序进程就不会再有父子关系了。 下面我们从 pomelo.createApp 调用开始,来梳理 pomelo 的启动过程。 首先我们使用 pomelo start,此时命令行工具 pomelo 会检测 start 后面有没有其他参数,比如是否需要 daemon 的形式启动,后面的参数是否指定了 env 等,在这里,我们仅仅使用了 pomelo start,后面没有跟任何其他参数,此时命令行工具将会为其添加一个默认的 env 参数,即 env=develpment,然后就启动了 node.js 进程,如下:
`node /app.js env=development`
此时 pomelo start 就以没有过多参数的方式启动了app.js。

Application的初始化

接下来我们来分析app.js的执行:


如上面的时序图所示: 在 pomelo 的 createApp() 返回后,我们在 app.js 里,往往会对 app 进行一些配置,比如调用 app.set 设置一个上下文变量的值,app.route 调用配置个路由等。

Master 服务器启动

当执行完上面的用户编辑的代码后,将会进入到的是 app.start() 调用,当 app.start 调用时,首先会加载默认的组件,对于 master 服务器来说,其加载的默认组件为 master 组件和 monitor 组件。下面主要分析 master 组件在启动中的作用,分析一下 master 组件的启动过程:


如上面的时序图所示:

应用服务器启动

服务器的关闭

当我们调用了 pomelo start 启动了 master 服务器,master 服务器又启动了所有的应用服务器后,所有的服务器都进入到自己的事件循环中,接受外来的请求事件或者是自身的定时器事件执行相应的回调方法。
当我们想关闭服务器时候,我们可以很暴力地使用 Ctrl+C 直接结束掉所有的进程,也可以优雅地通过命令行工具执行 pomelo stop 进行关闭。实际上,命令行工具是作为 pomelo 管理框架中的 client 角色的,它使用的 Module 是 pomelo 内建的 console,通过 console Module 给 master 服务器发出关闭服务器请求,master 会给每一个服务器发出停止通告。每个应用服务器接收到 stop 通告后,回调函数里面会调用 app.stop,app.stop 则会如上面图中那样,按照加载的逆序分别调用每一个组件的 stop 回调方法。当所有的组件的 stop 调用完后,服务器完成关闭。master 在发出停止通告后,自己稍作等待也调用 app.stop,stop 掉自己加载的组件完成关闭。

总结

我们在这里阐述了 pomelo 应用从启动到关闭的整个流程,pomelo 应用的整个流程实际就是对其所加载的组件的生命周期的管理过程,pomelo 的核心功能都由其组件提供。每一个组件在导出的时候,往往导出的都是一个工厂函数,通过工厂函数,app 在加载的时候才会创建相应的组件。app 在整个 pomelo 应用中,并不执行逻辑业务,它仅仅被当作一个全程驱动的入口以及一个上下文环境。对整个应用其关键性的调用为 app 的 start 调用和 app.stop 调用,其中 app.start 启动服务器,app.stop 关闭服务器。app.start 一般都是在 app.js 中由用户来调用,而 app.stop 一般都是系统的某个组件接受到停止服务器请求时进行的异步回调。关于具体加载的一些组件的功能,将在相关部分进行详述。


来源:摘自 https://github.com/NetEase/pomelo/wiki/%E6%A1%86%E6%9E%B6%E9%A9%B1%E5%8A%A8,本站 行痴 整理