what's FastCGi for php

preface

  公司全部的大多数业务都泡在LNMP平台上,因此对PHP+Nginx有点了解,那么就作个小小的总结吧。php

what's FastCGi

  FastCGI是一个可伸缩,高速的在HTTP server和动态脚本语言间通讯的接口。FastCGI支持多种脚本语言和HTTP server。
  FCGI是由CGI发展改进而来的。传统的CGI接口方式的性能不好。每次HTTP服务器遇到动态程序时都须要从新启动脚本解释器来执行解析,而后将结果返回给HTTP服务器,这在处理高并发访问时几乎是不可用的。另外传统的CGI接口方式安全性也不好,如今不多使用了。
  FCGI接口方式采用C/S结构,能够将HTTP服务器和脚本解释器分开,同时在脚本解释器上启动一个或者多个脚本解释器守护进程。当HTTP服务器遇到动态程序时,能够将其直接交付给FCGI进程来执行,而后将获得的结果返回给浏览器。这种方式可让HTTP服务器专注的处理静态请求或者动态脚本的结果返回给客户端,这就很大程度上提升了响应速度。html

Nginx + FCGI运行原理

  Nginx 不支持对外部程序的直接调用或者解析,全部的外部程序(包括PHP)必须经过FCGI接口来调用。FCGI接口在linux是socket(这个socket是文件socket,也能够是ip socket)。为了调用CGI程序,还须要一个FCGI的wrapper(wrapper能够理解为启动另外一个程序的程序)。这个wrapper绑定在某个固定的socket上,如端口或者文件的socket,当Nginx将cgi请求发送给这个socket的时候,经过FCGI接口,wrapper接收到请求,而后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取数据,接着,wrapper将返回的数据经过FCGi接口,沿着固定的socket传给Nginx,最终,NGinx将返回的数据发送给客户端,这就是Nginx+FCGi的运行流程。如图所示:
前端

spawn-fcgi 和 php-fpm

  FCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称为fastCgi引擎,spawn-fcgi 和 PHP-FPM就是支持php的两个Fcgi进程管理器。
  span-fcgi是HTTP服务器lighttpd的一部分,目前是独立的一个项目,通常与lighttpd配合使用来支持PHP,可是lighttpd的spwan-fcgi在高并发访问的时候,会出现内存泄漏甚至自动重启FastCGI的问题
  Nginx是个轻量级的HTTPserver,必须借助第三方的FCGI处理器才能够对PHP进行解析。
  PHP-FPM是一个第三方的FCGI进程管理器,它是PHP的一个补丁来开发的,在安装的时候也须要和PHP源码一块儿编译,也就是说PHP-FPM被编译到PHP内核中,所以处理性能方面更加优秀,同事PHP-FPM在处理高并发方面也比spawn-fcgi引擎好不少,因此推荐NGINX+PHP-FPM组合。linux

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

那么就部署它们吧

  php下载地址: http://php.net
  php-fpm下载地址:http://php-fpm.org/downloads/
  我这里下载的php是php-5.5.38
  安装以前,把依赖包都安装好,采用yum安装 :c++

yum -y install gcc gcc++ libxml2 libxml2-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel zlib zlib-devel glibc-devel glib2 glib2-devel

安装好依赖包后,安装phpweb

./configure --prefix=/usr  /local/php --enable-fpm --enable-fastcgi(可能会提示没有这个选项)
    make && make install

  编译没有问题后,咱们开始配置和优化php-fpm,php全局配置文件是php.ini,编译后是在/etc/php.ini这下面。redis

重点介绍php-fpm引擎的配置文件
php-fpm配置文件也在/etc/php-fpm.conf下面,默认状况下会把/etc/php-fpm.d/www.conf 的配置文件include进去。vim

咱们在www.conf里面看看如下几项:
    listen = 127.0.0.1:9000 #监听了本地9k端口
    user = nginx     #运行用户
    group = nginx
    pm.max_children = 50        # 设置fcgi的进程数,官方建议小于2G内存开启64个,4G能够开200个
    request_terminate_timeout = 0   # 用于设置FCGI执行脚本的时间,默认是0秒,也就是五险的执行下去,能够更加状况改
    rlimit_files = 1024 #设置PHP-FPM 打开文件描述符的限制,这个值要和linux内核打开文件数关联起来,例如,要将此值设置为65535,就必须在linux命令上执行ulimit -HSN 65536
    pm.max_requests = 500  设置处理多少个请求后便会关闭,默认是500,
    listen.allowed_clients = 127.0.0.1    # 设置容许访问FCGI进程解析器的IP地址,若是不在IP地址,将没法接受Nginx转发过来的php解析请求。

了解完上诉配置后,就能够启动FastCGI了,启动命令以下:后端

[root@salt ~]# php-fpm        启动php-fpm

若是有像这样的报错:

[root@salt php]# php-cgi 
    PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/redis.so' - /usr/lib64/php/modules/redis.so: undefined symbol: igbinary_unserialize in Unknown on line 0

那么在/etc/php.ini把这行注释掉启动就能够了:

;  extension=/usr/lib64/php/modules/redis.so

Notice

若是是php7.0版本以上的,可使用如下命令安装redis

[root@salt ~]# pecl install redis
pecl/redis requires PHP (version >= 7.0.0, version <= 7.1.0, excluded versions: 6.0.0),              installed version is 5.5.32
No valid packages found
install failed

配置nginx来支持php
咱们切换到nginx配置文件目录下,发现有个default.conf的模版文件,咱们copy一份来修改后便可用,命令以下:

[root@salt ~]# cd /etc/nginx/conf.d/
[root@salt conf.d]# ls
default.conf
[root@salt conf.d]# cp default.conf web1.conf
[root@salt conf.d]# mv default.conf default.cf    # 避免默认配置影响nginx运行
[root@salt conf.d]# vim web1.conf 
# 写入如下内容:
server {
    listen       80;
    server_name  web1.test.com;
    charset utf8;
    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    location ~ \.php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;;
        include        fastcgi_params;
    }
}

参数解释

  • location 正则匹配到以php结尾的到这里解析,
  • root 指明了网站目录
  • fastcgi_pass 指明了用哪里的php-fpm来解析
  • fastcgi_index 指明首页
  • fastcgi_param 指明的是php动态程序的主目录,/scripts也就是$fastcgi_script_name前面指定的路径,咱们通常在这里写网站根目录的路径,好比咱们的路径是 /var/www/html。

测试php+nginx是否正常工做

在网站根目录下面建立Index.php文件,写入一些内容,命令以下:

/var/www/html/index.html的内容:
<h1>
    <span> hello, this is test page </span>
</h1>
/var/www/html/phpinfo.php内容:
<?php phpinfo(); ?>

咱们访问http://ip/若是出现自定义页面,那么就成功了。
访问http://ip/phpinfo.php 出现php安装信息,那么也算成功了。

优化Nginx和FastCgi参数

咱们在nginx配置文件里面的http段内添加一下内容,好比咱们如今使用的web1.conf文件,那么我就在web1.conf里面添加如下内容:

fastcgi_connect_timeout 300;    
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;

参数解释

  • fastcgi_connect_timeout 300;` 值链接到后端FastCGI的超时时间
  • fastcgi_send_timeout 300; 指向Fastcgi 传送请求的超时时间,这个值是已经完成了2次握手后向FastCGI应答的超时时间
  • fastcgi_read_timeout 300; 指向接收FastCGI应答的超时时间,这个是已经完成2次握手后接收FastCGI应答的超时时间
  • fastcgi_buffer_size 64k; 用于指定读取FastCGI。 应答第一部分须要多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),能够设置Fastcgi_buffers选项指定的缓冲区大小。
  • fastcgi_buffers 4 64k; 指定本地须要多少和多大的缓冲区缓冲FastCGI的应答请求。若是一个PHP脚本所产生的页面大小为256KB,那么就会为其分配4个64KB的缓冲区来缓存,若是页面大小大于256KB,那么大于256KB的部分会缓存到Fastcgi_temp指定的路径中。可是这个不是好办法。由于内存中的数据处理速度大于硬盘,通常这个值应该为站点中的php脚本所产生的页面大小的中间值,若是站点大部分脚本所产生的页面大小为256KB,那么能够把这个值设置为16 16K,或者4 64KB。。
  • fastcgi_busy_buffers_size 128k; 默认值是fastcgi_buffers的两 倍
  • fastcgi_temp_file_write_size 128k; 表示写入缓存文件时使用多大的数据块,默认是fastcgi_buffers的两倍。
  • 开启缓存后:
    fastcgi_cache_valid 200 302 1h;将http状态码是200的和302的缓存一小时,301的缓存一天,其余的缓存一分钟

  • fastcgi_cache_valid 301 1d;
  • fastcgi_cache_valid any 1m;

写完以上参数后,保存退出重启服务。

相关文章
相关标签/搜索