标题:【Nginx19】Nginx学习:FastCGI模块(一)基础配置

文章目录
    分类:存储运维 标签:Nginx

    Nginx学习:FastCGI模块(一)基础配置

    万众瞩目啊,总算到 FastCGI 了。看我文章和视频的各位大佬们8成以上都是 PHPer 吧,要做 PHP ,FastCGI 的配置就少不了。CGI 、FastCGI 、PHP-FPM 这些概念,咱们在很早之前的 了解PHP-FPM https://mp.weixin.qq.com/s/NUpDnfYfbPuWmal4Am3lsg 这篇文章中就学习过了。不记得的小伙伴可以回去看下哦,如果感觉说得太简单了,大家还可以去自己搜索一下相关的资料。


    FastCGI 模块的全称是 ngx_http_fastcgi_module ,包含在核心源码中,不需要单独编译了。

    基本配置

    还是拿我们在 HTTP 核心模块中第一篇文章中的例子来说。最简单的配置就是下面这样。

    location ~ \.php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }

    没错,就这么简单的几个配置,我们后面会一一说明它们的作用。标准的连接 PHP-FPM 就是这么简单,但是,CGI 是通用网关接口,因此,不仅仅是 PHP ,Python、Java、C++ 之类的任何语言,只要是实现了 FastCGI 接口,那么他们都可以通过这种形式与 Nginx 进行交互。并且 FastCGI 也提供这些语言的 API ,只不过我对这些语言不熟悉,而且大部分情况下,使用 Nginx 的 FastCGI 都是和 PHP 打配合的,因此,咱们也就不多赘述了。有兴趣,并且精通这些语言的小伙伴可以自己找资料调试一下哦。


    接下来,我们今天就先看看上面这个配置中的这三条配置指令是干嘛的。

    fastcgi_pass

    设置 FastCGI 服务器的地址。

    fastcgi_pass address;

    没有默认值,也可以将这个配置项当做是 FastCGI 的开关。它只能配置在 location 子模块中,也就是说,必须是指定路径的或者条件的 location 才能使用 FastCGI 。


    它的参数就一个,之前我们就学习过,可以使用 127.0.0.1:9000 这种端口形式的,也可以使用 unix:/var/sock/php-fpm/www.sock 这种形式。在开头 PHP-FPM 的文章中有过详细的说明。一般来说,本机使用,肯定是 UnixSocket 这种形式更好啦,毕竟不需要再走连接请求了。而且一般也很少人会把 Nginx 和 PHP-FPM 分开放,即使是做负载均衡,也是直接代理到每台主机的 Nginx 端口上。因此,建议本机的 Nginx+PHP 组合尽量都走 UnixSocket 。


    另外,这个服务器地址也可以是一组服务器,会以循环的方式请求,类似于默认的负载均衡配置,不过还是那句话,很少有人这么玩。详细的负载均衡 upstream 模块我们后面也会学到,主要还是看那边的吧。


    地址参数还可以包含变量,并且如果地址被指定为域名,则在所描述的服务器组中搜索该名称,如果没有找到,则使用解析器来确定。

    fastcgi_index

    $fastcgi_script_name 变量的值中设置将附加在以斜杠结尾的 URI 之后的文件名。

    fastcgi_index name;

    其实和大家最常见的那个 index 是一样的,只不过 index 是拼接到 root 或者 alias 路径的后面,而这个配置,则是将指定的默认文件拼接到以斜杠结尾的 $fastcgi_script_name 变量的后面。这个变量又是哪里来的呢?它呀,就是 FastCGI 当中的 $uri 变量,也就是我们的请求 URI 。

    • $fastcgi_script_name 请求 URI,如果 URI 以斜杠结尾,则请求带有由 fastcgi_index 指令配置的索引文件名附加到它的 URI。此变量可用于设置确定 PHP 中脚本名称的 SCRIPT_FILENAME 和 PATH_TRANSLATED 参数。比如说,我们请求配置一个 /php/ 路径,加上上面的 FactCGI 配置。

    location /php/ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /home/www/html1/php$fastcgi_script_name;
        include        fastcgi_params;
    }

    然后请求 /php/info/ ,那么实际访问的就是 $fastcgi_script_name 也就是 /php/info/ ,完整的 SCRIPT_FILENAME 路径就是 /home/www/html1/php/info/ ,最后拼上 fastcgi_index 的设置,它是针对 $fastcgi_script_name 的,因此当前其实 $fastcgi_script_name 的内容是 /php/info/index.php 。最终,完整的访问到的文件就是 /home/www/html1/php/info/index.php 。


    需要注意的是,如果我们访问的是静态页面,那么还是会走 root 或者 alias 的,不会走到 FastCGI 配置的路径中。而且,之前的文章也说过了,SCRIPT_FILENAME 指定的路径需要是绝对路径,这个也是容易配错的地方。

    fastcgi_param

    设置应传递给 FastCGI 服务器的参数。

    fastcgi_param parameter value [if_not_empty];

    没有默认值,但可以配置在 http、server、location 模块中。它的 value 值可以包含文本、变量及其组合。当且仅当当前级别上没有定义 fastcgi_param 指令时,这些指令才从上级的配置级别继承。一般来说,PHP 必须的主要是这两个。

    fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
    fastcgi_param QUERY_STRING    $query_string;

    SCRIPT_FILENAME 不用多说,PHP-FPM 要执行文件就要看它。但是我们的配置文件中没有写下面这个 QUERY_STRING 呀,注意哦,在我们的配置中,fastcgi_param 下面还 include 了一个文件。我们打开这个文件看看。

    // vim /etc/nginx/fastcgi_params
    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  REQUEST_SCHEME     $scheme; #请求协议 http/https
    fastcgi_param  HTTPS              $https if_not_empty; # 是否使用 https
    
    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
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;  # 仅 PHP 可用,如果PHP编译的时候使用了--enable-force-cgi-redirect 指令,REDIRECT_STATUS参数应该传输200.
    
    

    看到了吧,其实就是 Nginx 已经帮我们准备好了一堆配置。这些东西我们在 PHP 的 $_SERVER 中可以获取到。比如我们我们添加一个,在外面的 location 中添加吧,尽量还是不动这个默认的 fastcgi_params 配置文件。需要修改哪个值的话也可以通过前后顺序覆盖修改。一定要修改原始的这个 fastcgi_params 文件也可以,因为默认还有一个 fastcgi_params.default 文件会在它的同级目录中,如果没有这个文件的话,记得备份一下哦。

    location ~ \.php$ {
        ………………
        include        fastcgi_params;
        fastcgi_param os_PPP "zyblog"; # 新添加的
        fastcgi_param SERVER_SOFTWARE nnn; # 覆盖掉原始的值 nginx/1.23.0 ,变成 nnn
    }

    大小写没事,普通变量的命名规则就好了。然后在 php 文件中打印 $_SERVER,就可以看到新配置的这个信息。

    Array
    (
    ………………
    [os_PPP] => zyblog
    ………………
    [SERVER_SOFTWARE] => nnn
    ………………
    )

    之前在讲命令行时,我们就讲过,如果是命令行运行 php 文件打印的 $_SERVER 和通过 phpcgi 以及 Nginx、Apache 打印的是不同的,这下知道这个 $_SERVER 里的参数是怎么来的了吧。


    另外还要注意的一点是,header 头里的,在 PHP 的 $_SERVER 中是以 HTTP_ 开头的,同样,Nginx 的 FastCGI 配置中也有单独添加请求头的,这个我们后面会学到。


    在默认的配置中,还有一个 if_not_empty 的可选参数,用于表示如果值不存在,就传送到 CGI 程序中。上面的例子中,我们没有开启 HTTPS 访问,所以在 PHP 中,HTTPS 也不会在 $_SERVER 中显示。

    总结

    今天的内容很短,但是最基础的 FastCGI 的配置我们都学习到了。其实到现在,一个正常的动态 LNMP 架构中的 N 和 P 部分就已经搭建完成了。使用 Nginx 来搭建 PHP 环境是不是非常地简单方便,这也是 PHP 在之前的 Web2.0 时代能够大行其道的原因。整个 LNMP 环境都不是特别复杂,而且还有很多一键安装以及面板工具,能够帮助我们在分分钟内就搭建起整个线上或者开发环境。


    除了 FastCGI 之外 ,Nginx 还提供了 uwsgi ,也就是 Python 以及 Python 框架常用的一类通讯协议。PHP 也可以实现通过 uwsgi 与 Nginx 联通,但是,多此一举嘛,正常情况下也没人这么干,PHP-FPM 提供的 FastCGI 已经是事实标配了。如果硬要玩的话,需要安装额外的操作系统扩展以及环境支持,还要学习 uwsgi 相关的知识。因此,在 HTTP 模块中,我们就不特意再去学习 uwsgi 相关模块的配置指令了,毕竟咱们是标准的 PHPer 。(它的指令和 FastCGI 的非常相似,功能也是大同小异)


    此外,还有一个 scgi 模块也不单独写了,都是差不多的。


    FastCGI 相关的配置指令还有很多,我们接下来还要继续学习,这时候可不要随便切换频道啦,一起继续前进吧!


    参考文档:


    http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

    视频链接

    微信文章地址:https://mp.weixin.qq.com/s/wKIDTk2aAuGB3b3c0KIWDw

    B站视频地址:https://www.bilibili.com/video/BV1fM411X73e/

    搜索
    关注