nginx.conf中的 fastcgi_pass 和 fastcgi_param 详解

袁志蒙 745次浏览

摘要:基本原理nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,...

基本原理

nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。

nginx一般是把请求发fastcgi管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被nginx。

fastcgi_pass

这个命令是指定将http代理到哪个fastcgi服务端接口。fastcgi_pass后面是填写fastcgi服务端地址的,这个地址可以是域地址,也可以是Uninx-域套接字,如下所示:

fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;

为什么会有两种fastcgi_pass?

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走的就更多了.

socket是神马?

Socket 可以被定义描述为两个应用通信通道的端点。一个 Socket 端点可以用 Socket 地址来描述, Socket 地址结构由 IP 地址,端口和使用协议组成( TCP or UDP )。http协议可以通过socket实现,socket在传输层上实现。从这个角度来说,socket介于应用层和传输层之间。但是socket作为一种进程通信机制,操作系统分配唯一一个socket号,是依赖于通信协议的,但是这个通信协议不仅仅是 tcp或udp,也可以是其它协议。

在同一台服务器上,用tcp socket与unix domain socket有什么区别?

如图所示,对于进程间通讯的两个程序,unix domain socket的流程不会走到TCP 那层,直接以文件形式,以stream socket通讯。如果是TCP socket,则需要走到IP层。对于非同一台服务器上,TCP socket走的就更多了。

nginx.conf中的 fastcgi_pass 和 fastcgi_param 详解

UNIX Domain Socket:

Nginx <=> socket <=> PHP-FPM

TCP Socket(本地回环):

Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM

TCP Socket(Nginx和PHP-FPM位于不同服务器,不过也只能这样):

Nginx <=> socket <=> TCP/IP <=> 物理层 <=> 路由器 <=> 物理层 <=> TCP/IP <=> socket <=> PHP-FPM

像mysql命令行客户端连接mysqld服务也类似有这两种方式:

使用Unix Socket连接(默认):

mysql -uroot -p --protocol=socket --socket=/tmp/mysql.sock

使用TCP连接:

mysql -uroot -p --protocol=tcp --host=127.0.0.1 --port=3306


php5.3之后的版本,php-fpm.conf里的listen的默认配置是127.0.0.1:9000,就不会生成php-fpm.sock,因此如果需要Nginx里的配置有链接tmp/php-fpm.sock的话,需要将listen的地址配置成和nginx的配置文件一致,同时保证这个路径已经存在,这样在启动./php-fpm的时候,会在对应路径上自动生成php-fpm.sock,例如:

让PHP-FPM使用Unix套接字

打开 /etc/php-fpm.d/www.conf 修改后如下:

;listen = 127.0.0.1:9000 listen = /var/run/php-fpm/php-fpm.sock

修改www.conf配置文件里的listen.mode=0666就可以设置默认权限,不用手动修改了,然后重新加载 PHP-FPM:

systemctl restart php-fpm.

接下修改nginx的配置和所有的虚拟主机:

fastcgi_pass 127.0.0.1:9000; ==>fastcgi_pass unix:/tmp/php-fpm.sock;

打开nginx.conf

vim /etc/nginx/conf.d/default.conf
fastcgi_pass unix:/tmp/php-fpm.sock;

最后重新加载 nginx:

systemctl restart nginx.

fastcgi_param

这个命令是设置fastcgi请求中的参数,具体设置的东西可以在$_SERVER中获取到。比如你想要设置当前的机器环境,可以使用fastcgi_param ENV test;来设置。

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['REMOTE_ADDR']

对于php来说,最少需要设置的变量有:

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


对于POST请求,还需要设置:

fastcgi_param REQUEST_METHOD content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param 还可以使用if_not_empty进行设置。意思是如果value非空才进行设置。
fastcgi_param HTTPS   $https if_not_empty;


fastcgi_index

这个命令设置了fastcgi默认使用的脚本。就是当 SCRIPT_FILENAME 没有命中脚本的时候,使用的就是fastcgi_index设置的脚本。


随机内容

表情

共2条评论
  • 网友评论:

    这个模板很不错!

    2023-03-16 19:46:09 回复

    点击加载
  • 网友评论:

    撒花撒花

    2023-03-13 23:43:57 回复

    点击加载