zoukankan      html  css  js  c++  java
  • FastCGI介绍及Nginx fastcgi配置优化

    FastCGI介绍

          FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。

        FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

        Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。详细的过程,如图所示

    快速通用网关接口(Fast Common Gateway Interface/FastCGI)是通用网关接口CGI)的改进,描述了客户端和服务器程序之间传输数据的一种标准。FastCGI致力于减少Web服务器CGI程式之间互动的开销,从而使服务器可以同时处理更多的Web请求。与为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI进程管理器管理,而不是web服务器。

    当进来一个请求时,Web 服务器把环境变量和这个页面请求通过一个unix domain socket(都位于同一物理服务器)或者一个IP Socket(FastCGI部署在其它物理服务器)传递给FastCGI进程。

    •  step1. Web 服务器启动时载入初始化FastCGI执行环境 。 例如IIS ISAPI、apache mod_fastcgi、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi
    •  step2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程并等待来自Web 服务器的连接。启动FastCGI进程时,可以配置以ip和UNIX 域socket两种方式启动。 
    •  step3. 当客户端请求到达Web 服务器时, Web 服务器将请求采用socket方式转发到 FastCGI主进程,FastCGI主进程选择并连接到一个CGI解释器。Web 服务器将CGI环境变量和标准输入发送到FastCGI子进程。
    •   step4. FastCGI子进程完成处理后将标准输出和错误信息从同一socket连接返回Web 服务器。当FastCGI子进程关闭连接时,请求便处理完成。
    •   step5. FastCGI子进程接着等待并处理来自Web 服务器的下一个连接。

    由于 FastCGI 程序并不需要不断的产生新进程,可以大大降低服务器的压力并且产生较高的应用效率。它的速度效率最少要比CGI 技术提高 5 倍以上。它还支持分布式的部署, 即 FastCGI 程序可以在web 服务器以外的主机上执行。

    CGI 就是所谓的短生存期应用程序,FastCGI 就是所谓的长生存期应用程序。FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。

    nginx配置示例

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    这个配置的意思是 在浏览器中访问的.php文件,实际读取的是 $document_root(网站根目录)下的.php文件 -- 也就是说当访问127.0.0.1/index.php的时候,需要读取网站根目录下面的index.php文件

    include fastcgi_params; fastcgi_params 文件中含有各个nginx常量的定义,默认情况 SCRIPT_FILENAME = $fastcgi_script_name

    Nginx涉及三类配置文件

    1. 基础文件 conf/nginx.conf 
    # 说明:nginx默认会引用该文件,该文件会做最通用的参数设置
    
    2. fastcgi参数文件 conf/fastcgi.conf 
    # 说明:fastcgi会设置所有站点通用参数
    
    3. 站点文件 如:conf/vhost/a.com.conf 可以有多个,放在vhost文件夹下

    nginx配置文件里指令的继承关系:Nginx配置文件分为好多块,常见的从外到内依次是「http」、「server」、「location」等等,缺省的继承关系是从外到内,也就是说内层块会自动获取外层块的值作为缺省值

    conf/fastcgi.conf内容:

    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;
    
    # 用一个文件或状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在
    try_files $fastcgi_script_name = 404;
    
    #可以自定义值,比如区分开发(dev)和生成环境(product),在php中用getenv('MY_ENV')或$_SERVER['MY_ENV']获取
    fastcgi_param MY_ENV "product";
    
    #防跨站设置
    fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/data/tmp/php/upload/:/proc/";

    需要说明的:Nginx有两份fastcgi配置文件,分别是旧的「fastcgi_params」和新的「fastcgi.conf」,它们没有太大的差异,唯一的区别是后者比前者多了一行「SCRIPT_FILENAME」的定义,只需要引用一份新的配置文件fastcgi.conf即可

    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;#脚本文件请求的路径
    fastcgi_param  QUERY_STRING       $query_string; #请求的参数;如?app=123
    fastcgi_param  REQUEST_METHOD     $request_method; #请求的动作(GET,POST)
    fastcgi_param  CONTENT_TYPE       $content_type; #请求头中的Content-Type字段
    fastcgi_param  CONTENT_LENGTH     $content_length; #请求头中的Content-length字段。
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name; #脚本名称
    fastcgi_param  REQUEST_URI        $request_uri; #请求的地址不带参数
    fastcgi_param  DOCUMENT_URI       $document_uri; #与$uri相同。
    fastcgi_param  DOCUMENT_ROOT      $document_root; #网站的根目录。在server配置中root指令中指定的值
    fastcgi_param  SERVER_PROTOCOL    $server_protocol; #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;#cgi 版本
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;#nginx 版本号,可修改、隐藏
    fastcgi_param  REMOTE_ADDR        $remote_addr; #客户端IP
    fastcgi_param  REMOTE_PORT        $remote_port; #客户端端口
    fastcgi_param  SERVER_ADDR        $server_addr; #服务器IP地址
    fastcgi_param  SERVER_PORT        $server_port; #服务器端口
    fastcgi_param  SERVER_NAME        $server_name; #服务器名,域名在server配置中指定的server_name
    #fastcgi_param  PATH_INFO         $path_info;#可自定义变量
    # PHP only, required if PHP was built with –enable-force-cgi-redirect
    #fastcgi_param  REDIRECT_STATUS    200;
    在php可打印出上面的服务环境变量
    如:echo $_SERVER['MY_ENV']

    Nginx中FastCGI参数的优化配置实例

      在配置完成Nginx+FastCGI之后,为了保证Nginx下PHP环境的高速稳定运行,需要添加一些FastCGI优化指令。下面给出一个优化实例,将下面代码添加到Nginx主配置文件中的HTTP层级

    fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; 
    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 TEST; 
    fastcgi_cache_valid 200 302 1h; 
    fastcgi_cache_valid 301 1d; 
    fastcgi_cache_valid any 1m;

    上述代码的含义:

    第一行代码是为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间。
    fastcgi_connect_timeout指定连接到后端FastCGI的超时时间。
    fastcgi_send_timeout指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间。
    fastcgi_read_timeout指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收FastCGI应答的超时时间。
    fastcgi_buffer_size用于指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小。
    fastcgi_buffers指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等。
    fastcgi_busy_buffers_size的默认值是fastcgi_buffers的两倍。
    fastcgi_temp_file_write_size表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍。
    fastcgi_cache表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也会引起很多问题,要视具体情况而定。
    fastcgi_cache_valid、fastcgi用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时,将301应答缓存1天,其他应答均缓存1分钟。

    参考链接:

    https://www.cnblogs.com/skynet/p/4173450.html

    https://www.cnblogs.com/yezhaohui/p/4377662.html

  • 相关阅读:
    仅当使用了列的列表并且 IDENTITY_INSERT 为 ON 时,才能为表'SpeType'中的标识列指定显式值
    SQL Server 创建作业系列问题
    常用WebService收集
    SQL Server中调用WebService的实例
    本地时间与格林威治时间相互转换
    $route和$router的区别?
    超详细的Canal入门,看这篇就够了!
    linux 安装redis 完整步骤
    什么是JSON
    The expression 'list' evaluated to a null value
  • 原文地址:https://www.cnblogs.com/xiewenming/p/8109292.html
Copyright © 2011-2022 走看看