摘要:基本原理nginx本身不能處理PHP,它只是個web服務(wù)器,當(dāng)接收到請求后,如果是php請求,則發(fā)給php解釋器處理,并把結(jié)果返回給客戶端。nginx一般是把請求發(fā)fastcgi管理進(jìn)程處理,...
基本原理
nginx本身不能處理PHP,它只是個web服務(wù)器,當(dāng)接收到請求后,如果是php請求,則發(fā)給php解釋器處理,并把結(jié)果返回給客戶端。
nginx一般是把請求發(fā)fastcgi管理進(jìn)程處理,fascgi管理進(jìn)程選擇cgi子進(jìn)程處理結(jié)果并返回被nginx。
fastcgi_pass
這個命令是指定將http代理到哪個fastcgi服務(wù)端接口。fastcgi_pass后面是填寫fastcgi服務(wù)端地址的,這個地址可以是域地址,也可以是Uninx-域套接字,如下所示:
fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
為什么會有兩種fastcgi_pass?
Nginx和PHP-FPM的進(jìn)程間通信有兩種方式,一種是TCP,一種是UNIX Domain Socket.
其中TCP是IP加端口,可以跨服務(wù)器.而UNIX Domain Socket不經(jīng)過網(wǎng)絡(luò),只能用于Nginx跟PHP-FPM都在同一服務(wù)器的場景.用哪種取決于你的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可用于兩個沒有親緣關(guān)系的進(jìn)程,是目前廣泛使用的IPC機(jī)制,比如X Window服務(wù)器和GUI程序之間就是通過UNIX Domain Socket通訊的.這種通信方式是發(fā)生在系統(tǒng)內(nèi)核里而不會在網(wǎng)絡(luò)里傳播.UNIX Domain Socket和長連接都能避免頻繁創(chuàng)建TCP短連接而導(dǎo)致TIME_WAIT連接過多的問題.對于進(jìn)程間通訊的兩個程序,UNIX Domain Socket的流程不會走到TCP那層,直接以文件形式,以stream socket通訊.如果是TCP Socket,則需要走到IP層,對于非同一臺服務(wù)器上,TCP Socket走的就更多了.
socket是神馬?
Socket 可以被定義描述為兩個應(yīng)用通信通道的端點(diǎn)。一個 Socket 端點(diǎn)可以用 Socket 地址來描述, Socket 地址結(jié)構(gòu)由 IP 地址,端口和使用協(xié)議組成( TCP or UDP )。http協(xié)議可以通過socket實(shí)現(xiàn),socket在傳輸層上實(shí)現(xiàn)。從這個角度來說,socket介于應(yīng)用層和傳輸層之間。但是socket作為一種進(jìn)程通信機(jī)制,操作系統(tǒng)分配唯一一個socket號,是依賴于通信協(xié)議的,但是這個通信協(xié)議不僅僅是 tcp或udp,也可以是其它協(xié)議。
在同一臺服務(wù)器上,用tcp socket與unix domain socket有什么區(qū)別?
如圖所示,對于進(jìn)程間通訊的兩個程序,unix domain socket的流程不會走到TCP 那層,直接以文件形式,以stream socket通訊。如果是TCP socket,則需要走到IP層。對于非同一臺服務(wù)器上,TCP socket走的就更多了。
UNIX Domain Socket:
Nginx <=> socket <=> PHP-FPM
TCP Socket(本地回環(huán)):
Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM
TCP Socket(Nginx和PHP-FPM位于不同服務(wù)器,不過也只能這樣):
Nginx <=> socket <=> TCP/IP <=> 物理層 <=> 路由器 <=> 物理層 <=> TCP/IP <=> socket <=> PHP-FPM
像mysql命令行客戶端連接mysqld服務(wù)也類似有這兩種方式:
使用Unix Socket連接(默認(rèn)):
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的默認(rèn)配置是127.0.0.1:9000,就不會生成php-fpm.sock,因此如果需要Nginx里的配置有鏈接tmp/php-fpm.sock的話,需要將listen的地址配置成和nginx的配置文件一致,同時保證這個路徑已經(jīng)存在,這樣在啟動./php-fpm的時候,會在對應(yīng)路徑上自動生成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就可以設(shè)置默認(rèn)權(quán)限,不用手動修改了,然后重新加載 PHP-FPM:
systemctl restart php-fpm.
接下修改nginx的配置和所有的虛擬主機(jī):
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
這個命令是設(shè)置fastcgi請求中的參數(shù),具體設(shè)置的東西可以在$_SERVER中獲取到。比如你想要設(shè)置當(dāng)前的機(jī)器環(huán)境,可以使用fastcgi_param ENV test;來設(shè)置。
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#腳本文件請求的路徑 fastcgi_param QUERY_STRING $query_string; #請求的參數(shù);如?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; #請求的地址不帶參數(shù) fastcgi_param DOCUMENT_URI $document_uri; #與$uri相同。 fastcgi_param DOCUMENT_ROOT $document_root; #網(wǎng)站的根目錄。在server配置中root指令中指定的值 fastcgi_param SERVER_PROTOCOL $server_protocol; #請求使用的協(xié)議,通常是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; #服務(wù)器IP地址 fastcgi_param SERVER_PORT $server_port; #服務(wù)器端口 fastcgi_param SERVER_NAME $server_name; #服務(wù)器名,域名在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可打印出上面的服務(wù)環(huán)境變量 如:echo $_SERVER['REMOTE_ADDR']
對于php來說,最少需要設(shè)置的變量有:
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string;
對于POST請求,還需要設(shè)置:
fastcgi_param REQUEST_METHOD content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param 還可以使用if_not_empty進(jìn)行設(shè)置。意思是如果value非空才進(jìn)行設(shè)置。 fastcgi_param HTTPS $https if_not_empty;
fastcgi_index
這個命令設(shè)置了fastcgi默認(rèn)使用的腳本。就是當(dāng) SCRIPT_FILENAME 沒有命中腳本的時候,使用的就是fastcgi_index設(shè)置的腳本。
網(wǎng)友評論:
這個模板很不錯!
2023-03-16 19:46:09 回復(fù)
網(wǎng)友評論:
撒花撒花
2023-03-13 23:43:57 回復(fù)