NGINX+fastcgi(cgi)运作原理

1.NGINX服务器原理
nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程。
master主要做以下几件事:

(1).接收来自外界的信号
(2).向各worker进程发送信号
(3).监控worker进程的运行状态,当worker进程退出后(异常情况下),
会自动重新启动新的worker进程。
而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等,他们同等竞争来自客户端的请求,各进程互相之间是独立 的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会 设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。nginx的进程模型,可以由下图来表示: 

chapter-2-1.png

因为master来管理worker进程,所以我们要操作nginx只需要与master进程通信就行了。master进程会接收来自外界发来的信号,再根据信号做不同的事情。所以我们要控制nginx,只需要通过kill向master进程发送信号就行了。
worker进程又是如何处理请求的呢?我们前面有提到,worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的 http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?首先,每个worker进程都是从master进程fork过来,在 master进程里面,先建立好需要listen的socket(listenfd)之后,然后再fork出多worker进程。所有worker进程 的listenfd会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有worker进程在注listenfd读事件前抢 accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。当一个worker进程在 accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。我们可 以看到,一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。

2.FAST_CGI模型
FAST_CGI实在CGI上改进而来的,在说FAST_CGI之前必须先说说CGI。CGI叫是公共网关接口,它实际上是一段程序。是外部应用程序与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程。上面讲到的nginx程序是不能直接调用外部程序的,要调用外部程序必须使用cig接口。nginx调用CGI的过程是这样的:

    1.浏览器通过HTML表单或超链接请求指向一个CGI应用程序的URL。

    2.nginx服务器收到请求后,nginx服务器的worker进程需要执行执行指定的CGI应用程序(此时CGI初始化,启动CGI应用程序。)

    3.CGI应用程序执行所需要的操作(通常是基于浏览者输入的内容)。

    4.CGI应用程序把结果格式化为nginx或浏览器能够理解的文档(通常是HTML网页),然后终止此CGI应用程序。

    5.nginx把结果返回到浏览器中。
FAST_CGI的过程和CGI差不多,不同在于FAST_CGI在服务器启动时载入FAST_CGI管理程序,这个管理程序自身初始化并启动多个子程序(这些子程序都是CGI程序),然后等待连接到来,当请求到达服务器时,FAST_CGI进程管理器选择并连接到一个CGI进程,同时服务器将CGI环境变量和标准输入发送到CGI程序,此时CGI程序就开始处理请求。处理完成后关闭此请求的连接(CGI程序不关闭继续运行),然后等待下次的请求连接。