我们在部署rails应用时,大多时候都使用Nginx+Passenger的方式部署,本文主要对此架构下 Passenger的作用及其工作原理进行梳理。
一、什么是Passenger?
Phusion Passenger是一个开源的Web应用服务器,它能够处理HTTP请求,管理进程和资源、
系统监控以及问题诊断。
二、Passenger主要作用
在Nginx+Passenger部署中,Passenger和Nginx集成,Passenger主要用作应用服务器,管理 进程和资源,而Nginx充当Web服务器,处理HTTP事物以及向客户端传送静态文件,他们的关系如下图所示:
那么,为什么要这样实现呢?
一方面这是因为Nginx并不是Ruby应用服务器,它不能直接运行Ruby应用程序,而对于Ruby应用(Rails应用)来说,它们自身不能使用HTTP(我们的rails应用运行的时候都是指定了应用服务器的),另一方面,一般来说应用 服务器在处理HTTP时没有Nginx等Web服务器 处理的好,毕竟像Nginx或者Apache这类Web 服务器能更好地处理I / O安全性,HTTP并发管理,连接超时等这类问题。
三、Passenger工作原理
1、Passenger架构
Passenger架构如下图所示,Passenger由多个组件以及进程组成,这种架构的好处就是稳定以及具备鲁棒性,相互独立的组件当遇到崩溃 的问题时可以单独重启该组件,这样就避免因为一个组件的问题导致整个系统瘫痪。
1-1、Web Server module
Web Server模块Passenger针对Nginx实现的一 个模块,它随着Nginx启动而被加载,当一个请求到达Nginx时,它主要检查此请求是否应该被Passenger所服务的应用程序处理,如果可以被 处理,则将请求转发至Passenger内核。
1-2、Passenger Core(HelperAgent)
Passenger内核主要负责以下几件事:
- 记录当前存在的应用程序进程;
- 对请求进行负载均衡(基于进程的);
- 应用程序进程生成。Passenger会根据需要去生成应用程序进程,以提升系统处理能力,当然Passenger所能生成的进程数量我们是可以控制的;
- 监控以及统计收集数据能力。Passenger能够记录应用程序内存使用率、处理请求数等等;
1-3、UstRouter(LoggingAgent)
Passenger Core和UstRouter协作,UstRouter主要负责将数据发往Union Station(一个Web 监控服务),如果我们没有明确指示Passenger要向Union Station发数据,那么Union Station将空闲状态,不消耗资源。
1-4、Watchdog
Passenger Core和UstRouter包含复杂的逻辑,因此它们在运行时可能出现导致崩溃的错误。 因此作为安全措施,它们都由看门狗监控。 如果其中任何一个崩溃,它们都由看门狗重新启动。
1-5、Command line tools 这个主要是一些方便用户使用的一些管理工具,例如查看Passenger运行状态、内存使用率、当前进程数等等。
2、启动流程
Nginx+Passenger部署的应用程序启动流程 如下:
- Web服务器启动。对于我们用户来说,我 只需要执行命令启动Nginx服务器即可;
- Web服务器启动Watchdog;
- Watchdog首先初始化服务器实例目录,这 个目录是一个临时目录,主要存放Passenger 实例可能会用到的文件;
- Watchdog启动Passenger Core和 UstRouter,这两个模块会分别进行初始化, 当初始化完毕后,它们会向watchdog返回启动成功的消息;
- Watchdog向Nginx中的Passenger Module返回启动成功的消息,当然如果启动失败则会记 录错误日志。
3、Passenger Core架构
我们知道Passenger Core是整个Passenger的核心,所以有必要了解其架构。Passenger Core的架构图如下:
Passenger Core包含两个子系统:请求处理子系统、应用程序池子系统。
3-1、请求处理子系统
来自客户端的请求首先会被Web服务器接收,然后Web服 务器将请求以SCGI格式发往Passenger Core的请求处理 子系统,该系统会对请求做一些处理,最终以HTTP响应 的形式返回给Web服务器,最后Web服务器解析响应并发给客户端。
3-2、应用程序池子系统 应用程序池子系统职责如下:
- 记录存在的应用程序进程;
- 产生进程;
- 将请求路由到合适的进程(负载均衡);
- 监控进程; 强制实施资源限制,确保不会产生太多进程,并能关闭内存使用率过高的进程;
- 根据需要重启应用程序进程。例如我们修改了应用程序中某些文件,但我们不用自己重启Web服务器;
- 重启崩溃的应用程序进程;
- 排队请求以及限制并发。每个进程会告知系统其所能处理的最大并发量,当超过这个阈值时,超出的请求将进入队列,等待。
3-3、进程产卵器子系统
这个系统其实是应用程序池子系统内的一个子系统,它主要职责就是产生应用程序进程并创建一个与之对应的Process对象。该子系统提供多种进程产卵方式:
- 直接产卵
- 智能产卵
4、应用程序进程产卵和加载
应用程序进程是通过Passenger Core进程产生的,产生一个进程涉及许多准备工作,例如设置 通信频道、设置当前工作目录、设置环境变量等等,这些准备工作由Spawner对象以及一些提供各种支持可执行文件组成。当准备工作完成后,接下在就是加载应用程序入口点,这个加载工作将 由加载器完成,这个加载器的实现和我们应用程序所使用的语言相关。 加载器程序可以和产卵器通过我们在准备阶段设置的通信频道进行通信,加载器程序加载应用程序所使用的语言环境,设置服务,最后向产卵器返回执行结果。