nginx整合phpphp
前段時間,在內網搭建了一個基於LNMP的我的cms站點,第一次接觸了nginx,最開始瞭解nginx只知道nginx是個web服務器,僅此而已。後來,又有一次是在內網搭建私有云(KodExplorer),環境是nginx+php+KodExplorer。這一次搭建我就想了解下nginx。因而便有了這篇文章。css
接下來的內容都是基於nginx+php+KodExplorer 而展開的。html
一、什麼是nginxnode
二、如何安裝nginxnginx
三、nginx是如何響應web請求web
四、什麼是fastcgishell
五、nginx的匹配規則和順序express
五、擴展segmentfault
1、什麼是nginx瀏覽器
nginx是一個高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP代理服務器。nginx是由俄羅斯人lgor Sysoev開發。Nginx因它的穩定性、豐富的功能集、示例配置文件和低系統資源消耗而聞名。國內像騰訊、新浪、網易等都開始部署使用Nginx。(以上摘自Nginx的官網 http://wiki.nginx.org/NginxChs)
2、如何安裝nginx
本次安裝採用的是自動化腳本安裝,具體的能夠參照個人另外一個博客,nginx自動化安裝腳本。
3、nginx是如何響應web請求
若是讓我用文字,可能我半天也說不明白,仍是從nginx.conf的配置文件上 來講明nginx是如何響應客戶端的請求的。
#定義nginx運行的用戶和用戶組,這也就解釋爲啥/data/www/html的用戶和用戶組都是www.www user www; #nginx的work進程數,通常是根據服務器的cpu總核心數而設定的。 worker_processes 2; #error_log /dev/null; #定義全局錯誤日誌, error_log /data/log/nginx_error.log info; #進程文件的pid pid logs/nginx.pid; #一個nginx進程打開的最多文件描述符數目。 worker_rlimit_nofile 8192; #設置nginx的工做模式與鏈接數上限 events { #epoll是Linux內核一種高性能I/O模型,能夠最大化的支持nginx。 use epoll; #單個進程最大鏈接數。 worker_connections 8192; } #nginx能夠被定位一個HTTP服務器,接下來設定就是如何響應客戶端對服務器的HTTP請求。 http { #文件擴展名與文件類型的映射表。 include mime.types; #默認文件類型模式 default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] $request ' '"$status" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /dev/null main; #默認編碼格式爲utf-8 charset utf-8; #上傳文件大小的限制 client_header_buffer_size 32k; #設定請求緩存的大小 large_client_header_buffers 4 32k; #服務器名字的hash表大小 server_names_hash_bucket_size 512; #開啓高效文件傳輸模式。 sendfile on; #防止網絡阻塞 tcp_nopush on; #長鏈接超時時間60秒 keepalive_timeout 60; #防止網絡阻塞 tcp_nodelay on; #設定請求緩存大小 client_max_body_size 10m; # client_body_buffer_size 128k; # proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; proxy_buffer_size 8k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_temp_path /dev/shm/proxy_temp; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE_ADDR $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #一個server塊,能夠當作是一個虛擬的主機。 server { #監聽80端口 listen 80; #服務器的名稱爲10.68.4.201,這裏也能夠寫域名,不過域名要在hosts文件中註釋說明。 server_name 10.68.4.201; #設定該虛擬主機的默認網站根目錄位置 root /data/www/html/kodexplorer3.12 ; #設定首頁索引文件的名稱 index index.html index.htm index.php; autoindex on; #匹配.php的請求就交給FastCGI處理。 location ~ [^/]\.php(/|$) { #fastcgi採用TCP的鏈接方式。 fastcgi_pass 127.0.0.1:9000; #fastcgi 默認首頁文件 fastcgi_index index.php; #這裏就是nginx把參數傳遞給fastcgi的的默認根站點目錄。 #fastcgi_param SCRIPT_FILENAME $SCRIPT$fastcgi_script_name;(默認項) fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } #查看nginx的狀態。 location /nginx_status { stub_status on; access_log off; } #靜態頁面和文件由nginx本身處理,默認保存30天。 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } #.js和.css文件交給nginx處理,保存12個小時。 location ~ .*\.(js|css)?$ { expires 12h; } } }
以上是我機器的nginx配置文件,配置文件中server { } 能夠當作是一個虛擬的主機,這個虛擬主機就會對用戶訪問的url進行解析,匹配。而後將匹配後的到的文件,返回給請求端。配置文件中能夠寫多個server { } 來應對不一樣的訪問
4、什麼是fastcgi
CGI也叫「公共網關接口」,是一種協議。HTTP服務器與其餘服務器上的程序進行「交談」的一種工具。當客戶端向nginx請求一個.html的靜態文件時,nginx會去root指向的目錄查找該文件併發送給客戶端,衆所周知,目前的網絡上的頁面,大都是動態的頁面,而動態的頁面每每嵌套函數,而這些函數nginx是沒法解釋的,就拿.php頁面來講,當客戶端向nginx服務器請求一個.php頁面,nginx知道本身沒法處理這個.php頁面,因而乎他便把這個請求轉給可以解釋這個頁面的程序也就是PHP軟件,那麼nginx向PHP程序傳遞這個請求的時候,就用到了CGI協議,CGI協議規定了,雙發要互傳哪些參數的當web服務器收到一個.php請求後,會啓動一個cgi程序,也就是PHP的解析器--php.ini。當PHP解析完成後,一樣經過cgi把解析後內容返回到nginx,由nginx整合後再向客戶端發送請求後的數據。當請求完成後,PHP進程也就退出。那麼當下一個請求過來後,一樣又要啓動PHP進程,cgi傳輸數據,結束進程。很是的浪費時間。而fastcgi php-fpm會是啓動一個master主進程,而後在啓用多個worker子進程。當有請求過來時,fastcgi會去調用worker進程完成數據的傳送。fastcgi高效在這裏。之後的PHP中把fastcgi歸入到程序中了。
本文參照網友@尹川解釋說明。原文 http://segmentfault.com/q/1010000000256516, 在此表示感謝。
Nginx 鏈接FastCGI有兩種方式:TCP和unix domain socket
TCP的鏈接方式是 fastcgi_pass 127.0.0.1:9000 ;
SOCKET的鏈接方式是 fastcgi_pass unix:/dev/shm/php-cgi.sock ;
記得當時在調整測試nginx時,當時fastcgi_param的默認項以下。
fastcgi_param SCRIPT_FILENAME $SCRIPT$fastcgi_script_name;
結果當我訪問http://10.68.4.201/index.php 瀏覽器報file not found的 錯誤。有時還報404的錯誤。由於$SCRIPT這個參數指的是/script目錄,而該目錄下並無index.php文件,固然就報錯,因此 這裏你能夠寫填寫你工程的絕對路徑 像 fastcgi_param SCRIPT_FILENAME /data/www/html/KodExplorer3.12$fastcgi_script_name; 這樣nginx就能夠找到文件並傳遞給PHP解析。
固然了,個人location沒有配那麼多(按照實際須要來。) 這時,當我在訪問http://10.68.4.201/index.php 就能夠打開網頁了。
5、nginx的匹配規則與順序。
當咱們經過url 向nginx服務器發送訪問請求時,nginx---server---location,nginx會根據location對客戶端訪問的url進行匹配。通常狀況下一個server模塊下能夠有多個location,多個location就對應着多種匹配規則。多個location就有多種訪問的url。
下面我來講下location的匹配規則。這裏要感謝這位博主 http://www.cnblogs.com/lidabo/p/4169396.html,一開始,我也對nginx的location的匹配規則很不瞭解,配來配去,常常出現403,404的錯誤。而後又搞不清,到底如何匹配。看了這位博主後,加上本身的實驗,開始對nginx的location配置匹配規則有了些許的認識。
server { } 塊下的location大體能夠分爲兩類(@這一種暫不考慮)一種是普通 location [=|^~|/xxx/a.html|/] { } ,另外一種是正則 location [~|~*] { } 。nginx官方給出的匹配順序是,nginx優先匹配普通location ,再去匹配正則location 。當普通和正則均有匹配項時,nginx採用正則location匹配的結果。
server { listen 8080; server_name www.cnin.com ; root /data/www/html; location / { index index1.html; } location ~ /nginx { index index3.html; } location /nginx { index index4.html; } }
[root@localhost conf]# curl http://www.cnin.com:8080/nginx/ this is index3.html [root@localhost conf]# curl http://www.cnin.com:8080/ this is index1.html
可是若是普通location 是一下三者狀況,nginx匹配普通location後,將再也不匹配正則location
location = / { ----嚴格匹配 index index2.html; } location ~ /nginx { index index3.html; } location ^~ /nginx { ----不繼續匹配正則 index index5.html; } location /nginx/index6.html { ----精確匹配 index index6.html; }
[root@localhost conf]# curl http://www.cnin.com:8080/ this is index2.html [root@localhost conf]# curl http://www.cnin.com:8080/nginx/ this is index5.html [root@localhost conf]# curl http://www.cnin.com:8080/nginx/index6.html this is index6.html
當nginx根據location去匹配URL時,譬如http://www.cnin.com:8080/nginx/index6.html。因爲server塊中寫了root /data/www/html server_name www.cnin.com:8080 因此 http://www.cnin.com:8080 恰好匹配上server塊的定義,那麼接下來的/nginx nginx就會在/data/www/html目錄下去尋找名叫 nginx的目錄或者文件。 若是沒有找到相關的 文件,嘗試屢次後無果後,nginx就會返回一個404錯誤。 若是有nginx目錄,可是沒有index文件,那麼一樣也會返回404錯誤。固然這裏nginx找到只是本地的文件,若是nginx是作轉發,則另談。
nginx匹配普通location時,與nginx.conf 中location書寫的順序無關。而當去匹配正則location時,則與書寫的順序有關。
location ~* /PNG/ { PNG index index7.html; |---->index7.html } location ~* /png/ { png index INDEX8.html; |---->INDEX8.html } |---->index9.html location ~ /png/ { index index9.html; }
[root@localhost conf]# curl http://www.cnin.com:8080/PNG/ this is index7.html [root@localhost conf]# curl http://www.cnin.com:8080/png/ <head><title>403 Forbidden</title></head>
就只改變了一處地方, http://www.cnin.com:8080/png/的答案卻千差萬別。
location ~ /PNG/ { PNG index index7.html; |---->index7.html } location ~* /png/ { png index INDEX8.html; |---->INDEX8.html } |---->index9.html location ~ /png/ { index index9.html; }
[root@localhost conf]# curl http://www.cnin.com:8080/PNG/ this is index7.html [root@localhost conf]# curl http://www.cnin.com:8080/png/ this is INDEX8.html
經過這個例子,咱們能夠驗證,當nginx匹配正則location時,是安裝nginx.conf配置文件書寫的順序進行匹配的。下面我來解釋下:當咱們訪問的是/PNG/時,nginx從上往下的搜索,搜索到第一個location ~* /PNG/ { } 時,恰好匹配,因而nginx就去/data/www/html/PNG/目錄下去尋找index7.html 文件,而PNG目錄下恰好有這個文件,因而把這個頁面處理後的結果返回給了請求端,也就打印出了 「this is index7.html」。而當咱們去訪問 /png/時,若是按照以前所講,nginx應該是找第二個location 即 location ~* /png/ { } 那麼,也就是打印 「this is INDEX8.html 」,但是nginx返回的倒是 403 錯誤頁面。通過個人測試發現,此時nginx匹配的倒是第一個location ~* /PNG/ { } ,也就是要去找index7.html,而/png/目錄下面沒有這個文件,nginx因而乎就報403錯誤(頁面找不到),若是你在png目錄下從新寫一個「echo this is /png/ index7.html > index7.html」 當你再訪問http://..../png/時,此時nginx就會打印「this is /png/ index7.html 。驗證了nginx匹配正則location 是按照書寫的順序來匹配的。爲何會這麼匹配。由於咱們再寫 /PNG/的location時,聲明瞭它是 ~* 不區分大小寫的。那麼url訪問/png/天然能夠匹配的上,因而就會去訪問index7.html ,只不過是在/png/目錄下面找index7.html,而不是在/PNG/目錄下找。 而若是我聲明的是location ~ /PNG/ { } 那麼nginx在訪問/png/時就再也不去匹配 location ~ /PNG/ { } 。
以上是nginx作爲HTTP服務器時,一些訪問匹配規則。
------------------------------------------------------------------------------------------------------------
nginx還能夠作代理服務器,那麼該如何配置location
location /PNGKK/ { proxy_pass http://10.68.4.201/index.php; } location ~ /staticd/ { ----這種寫法錯誤,nginx沒法啓動 proxy_pass http://10.68.4.201/index.php; } nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /usr/local/nginx/conf/nginx.conf:147 大體意思是說proxy_pass不能再含有URI的location中使用正則規則。
根據nginx的匹配規則,咱們知道,當用戶訪問 http://www.cnin.com:8080/PNGKK/ 時,nginx會去/data/www/html/下去尋找PNGKK的文件或目錄。而當nginx用來作轉發時,這個規則就不起做用了。通過個人測試,我發現,轉發的location xxx { } 中間能夠寫任意字符。