Nginx与PHP的交互

FastCGI模块模块容许nginx同FastCGI协同工做,而且控制哪些参数将被安全传递。php

1、CGI和FastCGI简介

一、什么是CGI

CGI 是Web 服务器运行时外部程序的规范接口,按CGI 编写的程序能够扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可经过数据库API 与数据库服务器等外部数据源进行通讯,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也能够将从浏览器得到的数据放到数据库中。几乎全部服务器都支持CGI,可用任何语言编写CGI。---引自百度css

传统CGI接口方式的主要缺点是性能不好,由于每次HTTP服务器遇到动态程序时都须要从新启动脚本解析器来执行解析,而后将结果返回给HTTP服务器。这在处理高并发访问时几乎是不可用的,另外传统的CGI接口方式安全性也不好,如今已经不多使用了。html

二、什么是 FastCGI

FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通讯的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等。同时FastCGI也被许多脚本语言支持,其中就有PHP。FastCGI是从CGI发展改进而来的。前端

FastCGI接口方式采nginx


用C/S结构,能够将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,能够将其直接交付给FastCGI进程来执行,而后将获得的结果返回给浏览器。
web

这种方式的优势:可让HTTP服务器专注地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提升了整个应用系统的性能。数据库

2、Nginx+FastCGI运行原理

一、运行原理

Nginx不支持对外部程序的直接调用或者解析,全部的外部程序(包括PHP)必须经过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket能够是文件socket,也能够是ip socket)。浏览器

wrapper:为了调用CGI程序,还须要一个FastCGI的wrapper(wrapper能够理解为用于启动另外一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,经过FastCGI接口,wrapper接收到请求,而后Fork(派生)出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据经过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据(html页面或者图片)发送给客户端。这就是Nginx+FastCGI的整个运做过程,如图1-3所示。安全

webp

因此,咱们首先须要一个wrapper,这个wrapper须要完成的工做:ruby

一、经过调用fastcgi(库)的函数经过socket和ningx通讯(读写socket是fastcgi内部实现的功能,对wrapper是非透明的)
二、调度thread,进行fork和kill
三、和application(php)进行通讯

Nginx是个轻量级的HTTP server,必须借助第三方的FastCGI处理器才能够对PHP进行解析,所以其实这样看来nginx是很是灵活的,它能够和任何第三方提供解析的处理器实现链接从而实现对PHP的解析(在nginx.conf中很容易设置)。

FastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称为FastCGI引擎。 spawn-fcgi与PHP-FPM就是支持PHP的两个FastCGI进程管理器。所以HTTPServer彻底解放出来,能够更好地进行响应和并发处理

FastCGI 的主要优势是把动态语言和HTTP Server分离开来,因此Nginx与PHP/PHP-FPM常常被部署在不一样的服务器上,以分担前端Nginx服务器的压力,使Nginx专注处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专注解析PHP动态请求。

二、Nginx+PHP-FPM

PHP-FPM是管理FastCGI的一个管理器,它做为PHP的插件存在,在安装PHP要想使用PHP-FPM时在老php的老版本(php5.3.3以前)就须要把PHP-FPM以补丁的形式安装到PHP中,并且PHP要与PHP-FPM版本一致,这是必须的)

PHP-FPM实际上是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可使用。

PHP5.3.3已经集成php-fpm了,再也不是第三方的包了。PHP-FPM提供了更好的PHP进程管理方式,能够有效控制内存和进程、能够平滑重载PHP配置,比spawn-fcgi具备更多优势,因此被PHP官方收录了。

在./configure的时候带 –enable-fpm参数便可开启PHP-FPM。fastcgi已经在php5.3.5的core中了,没必要在configure时添加 --enable-fastcgi了。老版本如php5.2的须要加此项。

三、配置信息

关于fastcgi的配置文件,目前fastcgi的配置文件通常放在nginx.conf同级目录下,配置文件形式,通常有两种:fastcgi.conf  和 fastcgi_params。不一样的nginx版本会有不一样的配置文件,这两个配置文件有一个很是重要的区别:

fastcgi_parames文件中缺乏下列配置:
fastcgi_param  SCRIPT_FILENAME    
document_rootfastcgi_script_name;

咱们能够打开fastcgi_parames文件加上上述行,也能够在要使用配置的地方动态添加。使得该配置生效。

当咱们安装Nginx和PHP-FPM完后,配置信息:

PHP-FPM的默认配置php-fpm.conf:

listen_address 127.0.0.1:9000 #这个表示php的fastcgi进程监听的ip地址以及端口start_serversmin_spare_serversmax_spare_servers

Nginx配置运行php: 编辑nginx.conf加入以下语句:

location ~ \.php$ { 
   root html;
   fastcgi_pass 127.0.0.1:9000; #指定了fastcgi进程侦听的端口,nginx就是经过这里与php交互的
   fastcgi_index index.php;    include fastcgi_params;
   fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
}

Nginx经过location指令,将全部以php为后缀的文件都交给127.0.0.1:9000来处理,而这里的IP地址和端口就是FastCGI进程监听的IP地址和端口。

输入命令 netstat -nlpt|grep php-fpm 会获得:
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 1057/php-fpm
这里的127.0.0.1:9000 就是监听本机9000端口的意思。

四、总体工做流程:

1)、FastCGI进程管理器php-fpm自身初始化,启动主进程php-fpm和启动start_servers个CGI 子进程。主进程php-fpm主要是管理fastcgi子进程,监听9000端口。fastcgi子进程等待来自Web Server的链接。

2)、当客户端请求到达Web Server Nginx是时,Nginx经过location指令,将全部以php为后缀的文件都交给127.0.0.1:9000来处理,即Nginx经过location指令,将全部以php为后缀的文件都交给127.0.0.1:9000来处理。

3)FastCGI进程管理器PHP-FPM选择并链接到一个子进程CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程。

4)、FastCGI子进程完成处理后将标准输出和错误信息从同一链接返回Web Server。当FastCGI子进程关闭链接时,请求便告处理完成。

5)、FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个链接。

简单来讲,当须要处理php请求时,nginx的worker进程会将请求移交给php-fpm的worker进程进行处理,也就是最开头所说的nginx调用了php,其实严格得讲是nginx间接调用php。

五、Nginx和PHP-FPM的通讯方式

Nginx和PHP-FPM的进程间通讯有两种方式

一种是TCP
一种是UNIX Domain Socket.

其中TCP是IP加端口,能够跨服务器。而UNIX Domain Socket不通过网络,只能用于Nginx跟PHP-FPM都在同一服务器的场景。

用哪一种取决于你的PHP-FPM配置:

方式1:
php-fpm.conf: listen = 127.0.0.1:9000
nginx.conf: fastcgi_pass 127.0.0.1:9000;

方式2:
php-fpm.conf: listen = /tmp/php-fpm.sock
nginx.conf: fastcgi_pass unix:/tmp/php-fpm.sock;

其中php-fpm.sock是一个文件,由php-fpm生成,类型是srw-rw----

UNIX Domain Socket可用于两个没有亲缘关系的进程,是目前普遍使用的IPC机制,好比X Window服务器和GUI程序之间就是经过UNIX Domain Socket通信的。这种通讯方式是发生在系统内核里而不会在网络里传播。UNIX Domain Socket和长链接都能避免频繁建立TCP短链接而致使TIME_WAIT链接过多的问题。对于进程间通信的两个程序,UNIX Domain Socket的流程不会走到TCP那层,直接以文件形式,以stream socket通信。若是是TCP Socket,则须要走到IP层,对于非同一台服务器上,TCP Socket走的就更多了。


做者:北山学者连接:https://www.jianshu.com/p/eab11cd1bb28来源:简书简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。

相关文章
相关标签/搜索