Nginx与PHP-FPM进程间通信:TCP与UNIX Domain Socket的两种fastcgi_pass方式详解
fastcgi_pass 127.0.0.1:9000; fastcgi 经由 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 或 UDP)组成。http 协议能够通过 socket 来实现,且 socket 是在传输层上实现的。从这个角度来看,socket处于应用层与传输层之间。然而,socket作为一种进程通信机制,操作系统会分配唯一一个socket号,并且这依赖于通信协议,而这个通信协议不只是tcp或udp,还可以是其他协议。
在同一台服务器上,tcp socket 和 unix domain socket 存在哪些区别呢?它们在服务器环境中的表现有所不同,各自具有独特的特性和适用场景。tcp socket 通常用于跨网络的通信,而 unix domain socket 主要用于同一台服务器内部的进程间通信。在数据传输的安全性、性能等方面,两者也有着各自的特点。
如图所示,对于进程间通讯的两个程序而言,unix domain socket 的流程不会抵达 TCP 那一层。它会直接以文件形式,通过 stream socket 进行通讯。倘若为 TCP socket,那么就需要抵达 IP 层。对于不在同一台服务器上的情况,TCP socket 所走的路径就更多了。
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 命令,以 root 用户身份登录,需要输入密码,使用的协议是 socket,套接字文件路径为 /tmp/mysql.sock。即通过 -u 参数指定用户为 root,-p 参数用于输入密码,--protocol=socket 明确协议为 socket,--socket=/tmp/mysql.sock 指定套接字文件的路径为 /tmp/mysql.sock。
使用TCP连接:
使用 MySQL 时,需要以 root 用户身份登录,输入密码,使用 TCP 协议,连接到本地主机 127.0.0.1 ,并使用端口 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
设置默认权限可通过修改配置文件里的 listen.mode=0666 来实现,无需手动修改,之后再重新加载 PHP-FPM 即可。
systemctl restart php-fpm.
接下修改nginx的配置和所有的虚拟主机:
同时也可以将 fastcgi_pass 设置为 unix:/tmp/php-fpm.sock;
打开nginx.conf
打开 vim 编辑器,编辑 /etc/nginx/conf.d/default.conf 文件。 fastcgi 会将请求传递到 unix 套接字 /tmp/php-fpm.sock 上。
最后重新加载 nginx:
systemctl restart nginx.
fastcgi_param
这个命令的作用是设置 fastcgi 请求里的参数,其具体设置的内容能够在 $_SERVER 中获取到。例如,若你希望设置当前的机器环境,就可以通过使用 fastcgi_param ENV test; 来进行设置。
此为脚本文件请求的路径 。 fastcgi_param QUERY_STRING 为请求的参数;例如?app=123 ;它表示请求的参数部分;像?app=123 这样的形式;这里的?app=123 就是 QUERY_STRING 的具体示例;query_string 就是请求参数的具体内容;比如?app=123 就是其中的一个例子;QUERY_STRING 对应的就是请求的参数;像这种?app=123 的情况就是 QUERY_STRING 的体现;query_string 所代表的就是请求的参数;例如像?app=123 这样的就是 QUERY_STRING 的相关内容;QUERY_STRING 指的是请求的参数;像?app=123 这样的就是其具体表现形式 fastcgi_param 表示请求的动作(GET 或 POST),这里的请求动作被赋值为 $request_method 。 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 DOCUMENT_URI; #此参数与$uri相同。 #其值为$document_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_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 配置中指定的 server_name fastcgi_param 用于设置 PATH_INFO 为 $path_info ;这是一个可自定义的变量 。 仅支持 PHP,如果 PHP 是通过 --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 会将 CONTENT_LENGTH 这个参数设置为 $content_length 。 fastcgi_param 能够通过 if_not_empty 来进行设置。其含义为,当 value 不为空时才会进行设置。 fastcgi_param HTTPS 。如果有值则为 $https ,否则为空 。
fastcgi_index
这个命令对 fastcgi 默认使用的脚本进行了设置。也就是说,在 SCRIPT_FILENAME 没有命中脚本的情况下,所使用的脚本就是 fastcgi_index 设置的脚本。
随机内容
YzmCMS v3.0正式发布
超级唯美的微型迷你车摄影
浅谈现在比较流行的各种PHP框架
vue脚手架是什么?
mysql事务隔离级别