摘要:基本原理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走的就更多了。
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设置的脚本。
网友评论:
这个模板很不错!
2023-03-16 19:46:09 回复
网友评论:
撒花撒花
2023-03-13 23:43:57 回复