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 { } 中间能够写任意字符。