标签 "nginx" 下的文章

查了下网络资料,对Nginx配置文件nginx.conf的理解整理如下:

#定义Nginx运行的用户和用户组
user www www;

#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;

#进程文件
pid /var/run/nginx.pid;

#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events {

	#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
	use epoll;
	
	#单个进程最大连接数(最大连接数=连接数*进程数)
	worker_connections 65535;
}

#设定http服务器
http {
	include mime.types; #文件扩展名与文件类型映射表
	default_type application/octet-stream; #默认文件类型
	#charset utf-8; #默认编码
	server_names_hash_bucket_size 128; #服务器名字的hash表大小
	client_header_buffer_size 32k; #上传文件大小限制
	large_client_header_buffers 4 64k; #设定请求缓
	client_max_body_size 8m; #设定请求缓
	sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
	autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
	tcp_nopush on; #防止网络阻塞
	tcp_nodelay on; #防止网络阻塞
	keepalive_timeout 120; #长连接超时时间,单位是秒

	#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
	fastcgi_connect_timeout 300;
	fastcgi_send_timeout 300;
	fastcgi_read_timeout 300;
	fastcgi_buffer_size 64k;
	fastcgi_buffers 4 64k;
	fastcgi_busy_buffers_size 128k;
	fastcgi_temp_file_write_size 128k;

	#gzip模块设置
	gzip on; #开启gzip压缩输出
	gzip_min_length 1k; #最小压缩文件大小
	gzip_buffers 4 16k; #压缩缓冲区
	gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
	gzip_comp_level 2; #压缩等级
	gzip_types text/plain application/x-javascript text/css application/xml;
	
	#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
	gzip_vary on;
	#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

	upstream snsgou.com {
		#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
		server 192.168.80.121:80 weight=3;
		server 192.168.80.122:80 weight=2;
		server 192.168.80.123:80 weight=3;
	}

	#虚拟主机的配置
	server {

		#监听端口
		listen 80;
		
		#域名可以有多个,用空格隔开
		server_name blog.snsgou.com snsgou.com;
		index index.html index.htm index.php;
		root /data/www/qianyunlai;

		location ~ .*.(php|php5)?$ {
			fastcgi_pass 127.0.0.1:9000;
			fastcgi_index index.php;
			include fastcgi.conf;
		}

		#图片缓存时间设置
		location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
			expires 10d;
		}

		#JS和CSS缓存时间设置
		location ~ .*.(js|css)?$ {
			expires 1h;
		}

		#日志格式设定
		log_format access '$remote_addr - $remote_user [$time_local] "$request" '
		'$status $body_bytes_sent "$http_referer" '
		'"$http_user_agent" $http_x_forwarded_for';
		
		#定义本虚拟主机的访问日志
		access_log /var/log/nginx/qianyunlai.log access;

		#对 "/" 启用反向代理
		location / {
			proxy_pass http://127.0.0.1:88;
			proxy_redirect off;
			proxy_set_header X-Real-IP $remote_addr;
			
			#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			
			#以下是一些反向代理的配置,可选。
			proxy_set_header Host $host;
			client_max_body_size 10m; #允许客户端请求的最大单文件字节数
			client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
			proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
			proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
			proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
			proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
			proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
			proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
			proxy_temp_file_write_size 64k;
			#设定缓存文件夹大小,大于这个值,将从upstream服务器传
		}

		#设定查看Nginx状态的地址
		location /NginxStatus {
			stub_status on;
			access_log on;
			auth_basic "NginxStatus";
			auth_basic_user_file conf/htpasswd;
			#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
		}

		#本地动静分离反向代理配置
		#所有jsp的页面均交由tomcat或resin处理
		location ~ .(jsp|jspx|do)?$ {
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_pass http://127.0.0.1:8080;
		}

		#所有静态文件由nginx直接读取不经过tomcat或resin
		location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
			expires 15d; 
		}
		
		location ~ .*.(js|css)?$ {
			expires 1h;
		}
	}
}

Nginx参数:

--prefix= 指向安装目录
--sbin-path 指向(执行)程序文件(nginx)
--conf-path= 指向配置文件(nginx.conf)
--error-log-path= 指向错误日志目录
--pid-path= 指向pid文件(nginx.pid)
--lock-path= 指向lock文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。)
--user= 指定程序运行时的非特权用户
--group= 指定程序运行时的非特权用户组
--builddir= 指向编译目录
--with-rtsig_module 启用rtsig模块支持(实时信号)
--with-select_module 启用select模块支持(一种轮询模式,不推荐在高载环境下使用)禁用:--without-select_module
--with-poll_module 启用poll模块支持(功能与select相同,与select特性相同,为一种轮询模式,不推荐在高载环境下使用)
--with-file-aio 启用file aio支持(一种APL文件传输格式)
--with-ipv6 启用ipv6支持
--with-http_ssl_module 启用ngx_http_ssl_module支持(使支持https请求,需已安装openssl)
--with-http_realip_module 启用ngx_http_realip_module支持(这个模块允许从请求标头更改客户端的IP地址值,默认为关)
--with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)
--with-http_xslt_module 启用ngx_http_xslt_module支持(过滤转换XML请求)
--with-http_image_filter_module 启用ngx_http_image_filter_module支持(传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到)
--with-http_geoip_module 启用ngx_http_geoip_module支持(该模块创建基于与MaxMind GeoIP二进制文件相配的客户端IP地址的ngx_http_geoip_module变量)
--with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本)
--with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启
--with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件)
--with-http_gzip_static_module 启用ngx_http_gzip_static_module支持(在线实时压缩输出数据流)
--with-http_random_index_module 启用ngx_http_random_index_module支持(从目录中随机挑选一个目录索引)
--with-http_secure_link_module 启用ngx_http_secure_link_module支持(计算和检查要求所需的安全链接网址)
--with-http_degradation_module 启用ngx_http_degradation_module支持(允许在内存不足的情况下返回204或444码)
--with-http_stub_status_module 启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态)
--without-http_charset_module 禁用ngx_http_charset_module支持(重新编码web页面,但只能是一个方向--服务器端到客户端,并且只有一个字节的编码可以被重新编码)
--without-http_gzip_module 禁用ngx_http_gzip_module支持(该模块同-with-http_gzip_static_module功能一样)
--without-http_ssi_module 禁用ngx_http_ssi_module支持(该模块提供了一个在输入端处理处理服务器包含文件(SSI)的过滤器,目前支持SSI命令的列表是不完整的)
--without-http_userid_module 禁用ngx_http_userid_module支持(该模块用来处理用来确定客户端后续请求的cookies)
--without-http_access_module 禁用ngx_http_access_module支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于ip地址)
--without-http_auth_basic_module禁用ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于http基本认证方法来保护你的站点或其部分内容)
--without-http_autoindex_module 禁用disable ngx_http_autoindex_module支持(该模块用于自动生成目录列表,只在ngx_http_index_module模块未找到索引文件时发出请求。)
--without-http_geo_module 禁用ngx_http_geo_module支持(创建一些变量,其值依赖于客户端的IP地址)
--without-http_map_module 禁用ngx_http_map_module支持(使用任意的键/值对设置配置变量)
--without-http_split_clients_module 禁用ngx_http_split_clients_module支持(该模块用来基于某些条件划分用户。条件如:ip地址、报头、cookies等等)
--without-http_referer_module 禁用disable ngx_http_referer_module支持(该模块用来过滤请求,拒绝报头中Referer值不正确的请求)
--without-http_rewrite_module 禁用ngx_http_rewrite_module支持(该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置。如果在server级别设置该选项,那么他们将在 location之前生效。如果在location还有更进一步的重写规则,location部分的规则依然会被执行。如果这个URI重写是因为location部分的规则造成的,那么 location部分会再次被执行作为新的URI。 这个循环会执行10次,然后Nginx会返回一个500错误。)
--without-http_proxy_module 禁用ngx_http_proxy_module支持(有关代理服务器)
--without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持(该模块允许Nginx 与FastCGI 进程交互,并通过传递参数来控制FastCGI 进程工作。 )FastCGI一个常驻型的公共网关接口。
--without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持(该模块用来医用uwsgi协议,uWSGI服务器相关)
--without-http_scgi_module 禁用ngx_http_scgi_module支持(该模块用来启用SCGI协议支持,SCGI协议是CGI协议的替代。它是一种应用程序与HTTP服务接口标准。它有些像FastCGI但他的设计 更容易实现。)
--without-http_memcached_module 禁用ngx_http_memcached_module支持(该模块用来提供简单的缓存,以提高系统效率)
--without-http_limit_zone_module 禁用ngx_http_limit_zone_module支持(该模块可以针对条件,进行会话的并发连接数控制)
--without-http_limit_req_module 禁用ngx_http_limit_req_module支持(该模块允许你对于一个地址进行请求数量的限制用一个给定的session或一个特定的事件)
--without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持(该模块在内存中常驻了一个1*1的透明GIF图像,可以被非常快速的调用)
--without-http_browser_module 禁用ngx_http_browser_module支持(该模块用来创建依赖于请求报头的值。如果浏览器为modern ,则$modern_browser等于modern_browser_value指令分配的值;如 果浏览器为old,则$ancient_browser等于 ancient_browser_value指令分配的值;如果浏览器为 MSIE中的任意版本,则 $msie等于1)
--without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持(该模块用于简单的负载均衡)
--with-http_perl_module 启用ngx_http_perl_module支持(该模块使nginx可以直接使用perl或通过ssi调用perl)
--with-perl_modules_path= 设定perl模块路径
--with-perl= 设定perl库文件路径
--http-log-path= 设定access log路径
--http-client-body-temp-path= 设定http客户端请求临时文件路径
--http-proxy-temp-path= 设定http代理临时文件路径
--http-fastcgi-temp-path= 设定http fastcgi临时文件路径
--http-uwsgi-temp-path= 设定http uwsgi临时文件路径
--http-scgi-temp-path= 设定http scgi临时文件路径
--without-http 禁用http server功能
--without-http-cache 禁用http cache功能
--with-mail 启用POP3/IMAP4/SMTP代理模块支持
--with-mail_ssl_module 启用ngx_mail_ssl_module支持
--without-mail_pop3_module 禁用pop3协议(POP3即邮局协议的第3个版本,它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。是因特网电子邮件的第一个离线协议标 准,POP3协议允许用户从服务器上把邮件存储到本地主机上,同时根据客户端的操作删除或保存在邮件服务器上的邮件。POP3协议是TCP/IP协议族中的一员,主要用于 支持使用客户端远程管理在服务器上的电子邮件)
--without-mail_imap_module 禁用imap协议(一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。IMAP协议运行在TCP/IP协议之上, 使用的端口是143。它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。)
--without-mail_smtp_module 禁用smtp协议(SMTP即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。)
--with-google_perftools_module 启用ngx_google_perftools_module支持(调试用,剖析程序性能瓶颈)
--with-cpp_test_module 启用ngx_cpp_test_module支持
--add-module= 启用外部模块支持
--with-cc= 指向C编译器路径
--with-cpp= 指向C预处理路径
--with-cc-opt= 设置C编译器参数(PCRE库,需要指定--with-cc-opt=”-I /usr/local/include”,如果使用select()函数则需要同时增加文件描述符数量,可以通过--with-cc- opt=”-D FD_SETSIZE=2048”指定。)
--with-ld-opt= 设置连接文件参数。(PCRE库,需要指定--with-ld-opt=”-L /usr/local/lib”。)
--with-cpu-opt= 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64
--without-pcre 禁用pcre库
--with-pcre 启用pcre库
--with-pcre= 指向pcre库文件目录
--with-pcre-opt= 在编译时为pcre库设置附加参数
--with-md5= 指向md5库文件目录(消息摘要算法第五版,用以提供消息的完整性保护)
--with-md5-opt= 在编译时为md5库设置附加参数
--with-md5-asm 使用md5汇编源
--with-sha1= 指向sha1库目录(数字签名算法,主要用于数字签名)
--with-sha1-opt= 在编译时为sha1库设置附加参数
--with-sha1-asm 使用sha1汇编源
--with-zlib= 指向zlib库目录
--with-zlib-opt= 在编译时为zlib设置附加参数
--with-zlib-asm= 为指定的CPU使用zlib汇编源进行优化,CPU类型为pentium, pentiumpro
--with-libatomic 为原子内存的更新操作的实现提供一个架构
--with-libatomic= 指向libatomic_ops安装目录
--with-openssl= 指向openssl安装目录
--with-openssl-opt 在编译时为openssl设置附加参数
--with-debug 启用debug日志

实例一:

./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6

实例二:

./configure --sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--with-pcre=/usr/local/src/pcre-8.21 \
--with-zlib=/usr/local/src/zlib-1.2.8 \
--with-openssl=/usr/local/src/openssl-1.0.1c
make
make install

一,Rewrite重写时带“?”(问号)参数的传递

很多人都会遇到需要将网站以前的旧URL转换到新版本的新URL来,但是有一些带有参数的地址由于涉及到参数名的变更,需要通过伪静态的方式实现跳转。但Apache和Ngnix的方法是不支持带参数的URL地址重写的(即:RewriteRule不会去匹配“?”后面的字符串的,需要用RewriteCond来匹配)。

例如:把 /abc?id=123 重定向到 /def.php?id=123 的写法:
方式一:
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=(.+)$
RewriteRule ^/abc$ /def.php?sid=%1 [L]
#注释1:RewriteCond %{QUERY_STRING} ^id=(.+)$ ,得到url中的变量,并通过“%N”的方式获取(参数名可以重写,而且参数值可以匹配)
#注释2:RewriteCond 里面需要提取的值可以用 %N 进行反向引用值,而RewriteRule里面还是需要用$N的来反向引用值

方式二:
RewriteEngine on
RewriteBase /
RewriteRule ^/abc$ /def.php [L,QSA]
#注释1:[QSA]表示保留重写url时“?”后面的参数(但参数名不可以重写,只会原样的保留)

官方文档解释(查询字符串):
Pattern不会按照查询字符串进行匹配。为了达到这个目的,你必须使用一个带有% {QUERY_STRING}变量的RewriteCond指令。当然,你也可以在替换字符串中创建包含查询字符串的URL:在替换字符串串中使用问号,以标明其后的部分应该被重新注入到QUERY_STRING中。而要删除一个已有的请求串,则可以用问号来终结替换字符串。为了联合新旧查询字符串,请使用[QSA]标志。

二、apache rewrite 终结篇:apache %{QUERY_STRING}
1.$n取得第n个参数值
RewriteRule ^sss/(.*)/(.*)$ zdz/index.php?arg1=$1&arg2=$2

2.query_string(%{QUERY_STRING}后为匹配的正则)
URL参数(Query String)是URL里面“?”后面的部分,它通常用于传输参数给CGI脚本或者其它动态页面。在Apache中,该值存储在环境变量QUERY_STRING中(在PHP中,可以通过$_SERVER['QUERY_STRING']访问到)。
在Apache中,大多对URL进行操作的指令,如、Redirect、Alias和RewriteRule,都不能直 接访问该数据;不过,mod_rewrite模块却可以对URL参数进行添加、删除和修改。其中的关键就是使用RewriteCond来匹配% {QUERY_STRING}变量,如果需要的话,还可以使用[QSA]标志来附加URL参数。

eg.1
如果 http://piaoyun.cc/rewrite/jeecn.zdz?par=helloforbworld 中的 query_string 包含字符串forb ,则禁止访问
RewriteCond %{QUERY_STRING} forb
RewriteRule ^(.*)\.(.*)$ preg.php?%{QUERY_STRING} [F]

eg.2
通过[QSA]标志保留原有URL参数的同时,在后面增加新的URL参数:param=value
RewriteRule ^/page /page?param=value [QSA]

eg3.
当URL参数包含字符串parm时
将URL:http://jeecn.com/ask?param=value 重写为: http://jeecn.com/answer?param=value
RewriteCond %{QUERY_STRING} parm
RewriteRule ^/ask /answer

eg4.%n反向引用
1)当访问 /path 时,将字符串 parm修改为 showparm
RewriteCond %{QUERY_STRING} ^(.*)parm(.*)$
RewriteRule /path /path?%1showparm%2
上面的%1和%2是反向引用,来自之前的RewriteCond中正则表达式的匹配结果

2)将http://jeecn.com/path?key=value 转换为: http://piaoyun.cc/path/key/value
RewriteCond %{QUERY_STRING} ^(\w+)=(\w+)$
RewriteRule ^/path /path/%1/%2?

LNMP有一个缺点就是目录权限设置上不如Apache,有时候网站程序存在上传漏洞或类似pathinfo的漏洞从而导致被上传了php木马,而给网站和服务器带来比较大危险。
建议将网站目录的PHP权限去掉,当访问上传目录下的php文件时就会返回403错误。下面详细介绍如何把lnmp环境下去掉指定目录的PHP执行权限。
那么在nginx里面同样可以实现这种方法,那就是location的优先匹配
首先要编辑nginx的虚拟主机配置,在fastcgi的location语句的前面按下面的内容添加:
1、单个目录去掉PHP执行权限

location ~ /attachments/.*.(php|php5)?$
{
deny all;
}

2、多个目录去掉PHP执行权限取消多个目录的php执行访问权限和模版目录文件的访问!
#取消多个目录的php执行访问权限和模版目录文件的访问!

location ~ /(uploadfile|piaoyun/templates|piaoyun)/.*\.(php|php5|html)?$
{
deny all;
}

注意这段secion一定要放在指定执行php section的前面才可以生效

添加完执行:

/usr/local/nginx/sbin/nginx -t

测试配置文件

执行:

/usr/local/nginx/sbin/nginx -s reload

载入配置文件使其生效

Nginx设置301重定向相对还是比较容易的,301永久重定向不仅能使页面实现自动跳转,而且对于搜索引擎来说,可以传递网站权重、收录以及PR值等。下面我们就详细说说Linux下Nginx设置301重定向的方法:

首先将多个域名指向同一web目录,代码如下:

server_name www.piaoyun.cc piaoyun.cc;

二、我们说下Nginx设置域名301重定向中常用的2种方法:

第一种方法是判断nginx核心变量host(老版本是http_host),适用于绑定多个域名,都相同用途的重定向:

server {
server_name www.piaoyun.cc piaoyun.cc;
if ($host != 'piaoyun.cc' ) {
rewrite ^/(.*)$ http://piaoyun.cc/$1 permanent;
}
...
}

第二种方法,适用于多个域名,但有域名有其他用途不需要重定向的情况:

server {
server_name www.piaoyun.cc piaoyun.cc download.piaoyun.cc;
if ($host = 'www.piaoyun.cc' ) {
rewrite ^/(.*)$ http://piaoyun.cc/$1 permanent;
}
...
}

上面的download.piaoyun.cc为频道域名,不需要重定向。

这两种方法中, permanent是关键,详细见下面nginx重定向规则说明。
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301

三、测试是否定向成功
SSH中输入指令:

/usr/local/nginx/sbin/nginx -t

提示:
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful

测试成功后,重启nginx,输入下面指令:

/usr/local/nginx/sbin/nginx -s reload

重启之后测试一下~是否成功设定完成! 输入指令~

下面另外说下Nginx设置目录如何重定向到目录的方法

例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:

location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.gz break;
}

nginx重定向的IF条件判断
在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:

1、匹配判断:
~ 为区分大小写匹配; !~为区分大小写不匹配
~* 为不区分大小写匹配;!~为不区分大小写不匹配

例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:

if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}

2、文件和目录判断
-f和!-f判断是否存在文件
-d和!-d判断是否存在目录
-e和!-e判断是否存在文件或目录
-x和!-x判断文件是否可执行

例如下面设定nginx在文件和目录不存在的时候重定向:

if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}
return

最近更换了lnmp环境,发现用自带的ecshop.conf的伪静态规则是无效的,不知道是我的设置有问题呢,还是其他问题,通过搜索找到了一个可以用的

正确的可以使用的规则如下:

location / {
    if (!-e $request_filename) {
        rewrite "^/index\.html" /index.php last;
        rewrite "^/category$" /index.php last;
        rewrite "^/feed-c([0-9]+)\.xml$" /feed.php?cat=$1 last;
        rewrite "^/feed-b([0-9]+)\.xml$" /feed.php?brand=$1 last;
        rewrite "^/feed\.xml$" /feed.php last;
        rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last;
        rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last;
        rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last;
        rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3 last;
        rewrite "^/category-([0-9]+)-b([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2 last;
        rewrite "^/category-([0-9]+)(.*)\.html$" /category.php?id=$1 last;
        rewrite "^/goods-([0-9]+)(.*)\.html" /goods.php?id=$1 last;
        rewrite "^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last;
        rewrite "^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$" /article_cat.php?id=$1&page=$2 last;
        rewrite "^/article_cat-([0-9]+)(.*)\.html$" /article_cat.php?id=$1 last;
        rewrite "^/article-([0-9]+)(.*)\.html$" /article.php?id=$1 last;
        rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html" /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last;
        rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2&page=$3 last;
        rewrite "^/brand-([0-9]+)-c([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2 last;
        rewrite "^/brand-([0-9]+)(.*)\.html" /brand.php?id=$1 last;
        rewrite "^/tag-(.*)\.html" /search.php?keywords=$1 last;
        rewrite "^/snatch-([0-9]+)\.html$" /snatch.php?id=$1 last;
        rewrite "^/group_buy-([0-9]+)\.html$" /group_buy.php?act=view&id=$1 last;
        rewrite "^/auction-([0-9]+)\.html$" /auction.php?act=view&id=$1 last;
        rewrite "^/exchange-id([0-9]+)(.*)\.html$" /exchange.php?id=$1&act=view last;
        rewrite "^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last;
        rewrite "^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last;
        rewrite "^/exchange-([0-9]+)-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2 last;
        rewrite "^/exchange-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1 last;
    }

    if (!-e $request_filename) {
        return 404;
    }
}

lnmp自带的规则如下(我使用无效):

if (!-e $request_filename)
{
rewrite "^/index\.html" /index.php last;
rewrite "^/category$" /index.php last;
rewrite "^/feed-c([0-9]+)\.xml$” /feed.php?cat=$1 last;
rewrite “^/feed-b([0-9]+)\.xml$” /feed.php?brand=$1 last;
rewrite “^/feed\.xml$” /feed.php last;
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$” /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2&page=$3 last;
rewrite “^/category-([0-9]+)-b([0-9]+)(.*)\.html$” /category.php?id=$1&brand=$2 last;
rewrite “^/category-([0-9]+)(.*)\.html$” /category.php?id=$1 last;
rewrite “^/goods-([0-9]+)(.*)\.html” /goods.php?id=$1 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$” /article_cat.php?id=$1&page=$2 last;
rewrite “^/article_cat-([0-9]+)(.*)\.html$” /article_cat.php?id=$1 last;
rewrite “^/article-([0-9]+)(.*)\.html$” /article.php?id=$1 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html” /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2&page=$3 last;
rewrite “^/brand-([0-9]+)-c([0-9]+)(.*)\.html” /brand.php?id=$1&cat=$2 last;
rewrite “^/brand-([0-9]+)(.*)\.html” /brand.php?id=$1 last;
rewrite “^/tag-(.*)\.html” /search.php?keywords=$1 last;
rewrite “^/snatch-([0-9]+)\.html$” /snatch.php?id=$1 last;
rewrite “^/group_buy-([0-9]+)\.html$” /group_buy.php?act=view&id=$1 last;
rewrite “^/auction-([0-9]+)\.html$” /auction.php?act=view&id=$1 last;
rewrite “^/exchange-id([0-9]+)(.*)\.html$” /exchange.php?id=$1&act=view last;
rewrite “^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last;
rewrite ^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last;
rewrite “^/exchange-([0-9]+)-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1&page=$2 last;
rewrite “^/exchange-([0-9]+)(.*)\.html$” /exchange.php?cat_id=$1 last;
}

什么是404页面
如果碰巧网站出了问题,或者用户试图访问一个并不存在的页面时,此时服务器会返回代码为404的错误信息,此时对应页面就是404页面。404页面的默认内容和具体的服务器有关。如果后台用的是NGINX服务器,那么404页面的内容则为:404 Not Found

为什么要自定义404页面
在访问时遇到上面这样的404错误页面,我想99%(未经调查,估计数据)的用户会把页面关掉,用户就这样悄悄的流失了。如果此时能有一个漂亮的页面能够引导用户去他想去的地方必然可以留住用户。因此,每一个网站都应该自定义自己的404页面。

nginx下如何自定义404页面
IIS和APACHE下自定义404页面的经验介绍文章已经非常多了,nginx的目前还比较少,为了解决自家的问题特地对此作了深入的研究。研究结果表明,NGINX下配置自定义的404页面是可行的,而且很简单,只需如下几步:

1.创建自己的404.html页面
2.更改nginx.conf在http定义区域加入:

fastcgi_intercept_errors on;

3.更改nginx.conf(或单独网站配置文件,例如在nginx -> sites-enabled下的站点配置文件 )中在server 区域加入:

error_page 404 /error/404.html;

或者

error_page 404 = http://piaoyun.cc/404.html;

4.更改后重启nginx,,测试nginx.conf正确性:

/usr/local/nginx/sbin/nginx –t

#502 等错误可以用同样的方法来配置。

error_page  500 502 503 504  /50x.html;

注意事项:
1.必须要添加:fastcgi_intercept_errors on; 如果这个选项没有设置,即使创建了404.html和配置了error_page也没有效果。fastcgi_intercept_errors 语法: fastcgi_intercept_errors on|off 默认: fastcgi_intercept_errors off 添加位置: http, server, location 默认情况下,nginx不支持自定义404错误页面,只有这个指令被设置为on,nginx才支持将404错误重定向。这里需要注意的是,并不是说设置了fastcgi_intercept_errors on,nginx就会将404错误重定向。在nginx中404错误重定向生效的前提是设置了fastcgi_intercept_errors on,并且正确的设置了error_page这个选项(包括语法和对应的404页面)
2.不要出于省事或者提高首页权重的目的将首页指定为404错误页面,也不要用其它方法跳转到首页。
3.自定义的404页面必须大于512字节,否则可能会出现IE默认的404页面。例如,假设自定义了404.html,大小只有11个字节(内容为:404错误)。

nginx可以为网站或目录甚至特定的文件设置密码认证。密码必须是crypt加密的。可以用apache的htpasswd来创建密码。

格式为:htpasswd -b -c site_pass username password

site_pass为密码文件。放在同nginx配置文件同一目录下,当然你也可以放在其它目录下,那在nginx的配置文件中就要写明绝对地址或相对当前目录的地址。
如果你输入htpasswd命令提示没有找到命令时,你需要安装httpd.如centos是yum install httpd
如果是为了给网站加上认证,可以直接将认证语句写在nginx的配置server段中。
如果是为了给目录加上认证,就需要写成目录形式了。同时,还要在目录中加上php的执行,否则php就会被下载而不执行了。

例如:基于整个网站的认证,auth_basic在php解释之前。

server {
listen       80;
server_name www.akii.org akii.org;
root  /www/akii;
index index.html index.htm index.php;

    auth_basic "input you user name and  password";
    auth_basic_user_file /usr/local/nginx/conf/vhost/nginx_passwd;

location ~ .php$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny  all;
}
access_log /logs/akii.org_access.log main;
}

针对目录的认证,在一个单独的location中,并且在该location中嵌套一个解释php的location,否则php文件不会执行并且会被下载。auth_basic在嵌套的location之后。

server {
listen       80;
server_name www.akii.org akii.org;
root  /www/akii;
index index.html index.htm index.php;

    location ~ ^/admin/.* {
        location ~ \.php$ {
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
        }
 
        auth_basic "auth";
        auth_basic_user_file /usr/local/nginx/conf/vhost/auth/admin.pass;
    }

location ~ .php$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}

location ~ /\.ht {
deny  all;
}
access_log /logs/akii.org_access.log main;
}

这里有一个细节,就是location ~ ^/admin/.* {…} 保护admin目录下的所有文件。如果你只设了/admin/ 那么直接输入/admin/index.php还是可以访问并且运行的。 ^/admin/.* 意为保护该目录下所有文件。当然,只需要一次认证。并不会每次请求或每请求一个文件都要认证一下。

本文只介绍Nginx的配置文件信息,以及如何在虚拟站点中使用PHP。

这里假定Nginx被安装在 /usr/local/nginx 目录下,PHP安装在 /usr/local/php 目录下。

一、Nginx主配置文件及解析

Nginx配置文件主要分为4部分:main(全局设置)部分设置的指令将影响其他所有设置;server(主机设置)部分的指令主要用于指定主机和端口;upstream(负载均衡服务器设置)部分指令主要用于负载均衡,设置一系列的后端服务器;location(URL匹配特定位置的设置)部分用于匹配网页位置。四者之间的关系:server继承main,location继承server,upstream既不会继承其他设置,也不会被继承。

 # 指定Nginx Worker进程运行用户以及用户组,默认由nobody账号运行。如果编译Nginx的时候指定了用户和用户组,该选项可以关闭
 user  www www;
 # 指定Nginx需要开启的进程数,每个进程平均耗费10~12M内存。建议数量设置成与CPU内核的数量一致就可以了。
 # cpu的核心数可以使用 cat /proc/cpuinfo | grep flags | grep ' lm ' | wc -l 或 cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 命令进行查
 worker_processes  1;
 # 定义全局错误日志文件,后面可以设置输出级别:debug、info、notice、warn、error、crit
 error_log  logs/error.log;
 #error_log  logs/error.log  notice;
 #error_log  logs/error.log  info;
 # 用来指定进程id的存储文件位置
 pid        logs/nginx.pid;
 # 启用TCMalloc的设置,见上节相关的描述
 google_perftools_profiles /tmp/tcmalloc;
 # 用于绑定worker进程和CPU,该值必须和Linux内核打开文件数关联起来,如将该值设置为65535就必须在Linux命令行中执行 ulimit -HSn 65535
 worker_rlimit_nofile 65535;

 events {
     # 用来指定Nginx的工作模式,支持的模式有select、poll、kqueue、epool、rtsig和/dev/poll。其中select和poll都是标准的工作模式
     # kqueue和epoll是高效的工作模式,前者用在linux平台上,后者用于BSD系统。
     use epoll;
     # 定义每个进程的最大连接数,默认是1024,该参数的最大连接数受Linux系统进程的最大打开文件数限制,必须使用 ulimit命令
     # 另外,最大客户端连接数max_client=worker_processes*worker_connections,作为反向代理的话还需要除以4。
     worker_connections  65535;
 }

 http {
     # 引用外部文件,类似于Apache中的include
     include       mime.types;
     # 当出现无法解析的文件时,提示用户下载
     default_type  application/octet-stream;

     # 定义日志的格式,后面的main为格式的名称,可以在access_log指令中进行引用
     #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  logs/access.log  main;

     # 设定请求缓冲
     server_names_hash_bucket_size 128;
     client_header_buffer_size 32k;
     large_client_header_buffers 4 32k;
     # 设置客户端能够上传文件大小的限制
     client_max_body_size 600m;

     # 是否开启高效文件传输模式,将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞
     sendfile        on;
     tcp_nopush     on;
     tcp_nodelay  on;

     # 隐藏nginx的版本显示,增强安全性
     server_tokens off;

     # 用于设置客户端连接保持活动的超时时间,单位为秒,默认为75s
     #keepalive_timeout  0;
     keepalive_timeout  65;
     # 用于指定响应客户端的超时时间,这个超时仅限于两个连接活动之间的时间,默认为60s
     #send_timeout 60;

     # 下面是FastCGI的优化指令
     # 连接到后端FastCGI的超时时间
     fastcgi_connect_timeout 300;
     # 向FastCGI传送请求的超时时间
     fastcgi_send_timeout 300;
     # 接收FastCGI应答的超时时间
     fastcgi_read_timeout 300;
     # 指定读取FastCGI应答第一部分需要多大的缓冲区
     fastcgi_buffer_size 64k;
     fastcgi_buffers 4 64k;
     # 默认值是fastcgi_buffers的两倍
     fastcgi_busy_buffers_size 128k;
     # 表示在写入缓存文件时使用多大的数据块,默认为fastcgi_buffers的两倍
     fastcgi_temp_file_write_size 128k;
     # 为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间
     #fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
     # 开启FastCGI缓存并为其设定一个名称。开启缓存可以有效降低CPU的负载,并且防止502错误的发生。
     # 但是同时也会引起很多问题,要视具体情况而定
     #fastcgi_cache TEST;
     # 用来指定应答代码的缓存时间,下面三条指令表示将200和303应答缓存1小时,301应答缓存1天,其他应答缓存1分钟。
     #fastcgi_cache_valid 200 302 1h;
     #fastcgi_cache_valid 301 1d;
     #fastcgi_cache_valid any 1m;

     # 配置Nginx的HttpGzip模块,开通的前提是安装的时候启用了该模块,使用 /usr/local/nginx/sbin/nginx -V 来查看安装的信息(大写的V)
     # 是否开通gzip
     gzip  on;
     # 允许压缩的页面最小字节数
     gzip_min_length 1k;
     gzip_buffers 4 16k;
     gzip_http_version 1.1;
     # 压缩比,从1到9,越大压缩率越高但越占资源,默认为1
     gzip_comp_level 2;
     # 指定压缩的类型,text/html总是被压缩
     gzip_types text/plain application/x-javascript text/css application/xml;
     # 是否让浏览器缓存压缩过的数据,默认为off
     gzip_vary on;

     # server 用于对虚拟主机的设置,建议每个站点的设置放到外部配置文件中,然后使用include进行引用
     # 这里设置一个默认的主机,当默认访问的时候返回403错误
     server {
         listen       80 default;
         server_name _;
         # 也可以修改成404或者500,根据自身情况进行设置
         return 403;
     }

     # 可以使用include将每个站点的配置引用进来,这样方便对站点进行管理
     include vhosts/piaoyun.cc.conf;
     include vhosts/abc.com.conf;
 }

二、Nginx设置虚拟主机及对PHP的支持

在conf目录下面创建vhosts目录,并创建站点的配置文件,这里以piaoyun.cc.conf为例。

[root@localhost ~]# cd /usr/local/nginx/
[root@localhost nginx]# mkdir -p conf/vhosts
[root@localhost nginx]# vim conf/vhosts/piaoyun.cc.conf

创建的piaoyun.cc.conf配置文件如下:

     # 虚拟主机以server进行定义
     server {
         # 监听的端口,多个端口之间使用空格进行间隔
         listen       80;
         # 用来定义访问的ip地址或者域名,多个域名之间使用空格分开
         server_name  examples.com www.examples.com;
         # 用于指定站点网页的默认编码格式
         charset utf-8;

         # 用来指定此站点的访问日志存放路径,后面的main用于设定日志的格式
         #access_log  logs/examples.com.access.log  main;

         # 用于指定站点的网页根目录,可以是相对路径(相对于nginx安装目录),也可以是绝对路径
         #root /www/examples.com
         # 用于指定访问的默认首页地址
         #index index.html index.php

         # 用来指定站点默认访问的设置,里面的root和index用法和效果与上面是一样的
         # 两种方式使用任何一种都是可以的,这里采用 location / {} 的方式
         location / {
             root   /www/examples.com;
             index  index.html index.php;
         }

         # 使用error_page指令设置各种错误信息的返回页面
         # 错误信息的返回页面大小如果低于512k则会被ie浏览器替换为ie默认的错误页面
         #error_page  404              /404.html;
         error_page   500 502 503 504 /50x.html;
         location = /50x.html {
             root   html;
         }

         # nginx的location指令用于设置url地址匹配,支持正则表达式匹配,也支持条件判断匹配。
         # 可以通过location指令实现nginx对动态、静态网页的过滤处理。
         # 下面是对所有的图片设置缓存30天
         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
             expires 30d;
         }
         # 对js和css文件缓存1小时
         location ~ .*\.(js|css)$ {
             expires 1h;
         }

         # 下面是列出了两种解析php的方式:
         # 第一种是简单的将所有以php结尾的请求都交给本机的8080端口进行处理
         #location ~ \.php$ {
         #    proxy_pass   http://127.0.0.1:8080;
         #}
         # 第二种是将php的请求交给FastCGI进程监听的ip地址及端口,这里转发给PHP_FPM
         location ~ \.php$ {
             # 设定用于解析php的根目录,通常为网站根目录
             root          /www/examples.com;
             # 地址和端口与php_fpm中设置的一致
             fastcgi_pass   127.0.0.1:9000;
             # 默认首页
             fastcgi_index  index.php;
             # 指定防止php动态程序的主目录,也就是$fastcgi_script_name前面指定的路径,建议与网站根目录一致或直接使用$document_root
             fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
             include        fastcgi_params;
         }

         # 防止直接访问 .htaccess 文件,建议开启
         location ~ /\.ht {
             deny  all;
         }
     }

最后创建网站的根目录并设置目录权限:

[root@localhost ~]# mkdir -p /www/examples.com
# 写入权限
[root@localhost ~]# chmod +w /www/examples.com
[root@localhost ~]# chown -R www:www /www/examples.com
# 创建一个测试的php文件
[root@localhost ~]# echo "<? phpinfo(); ?>" >> /www/examples.com/phpinfo.php

这个时候启动php-fpm和nginx之后,应该可以直接访问http://www.piaoyun.cc/phpinfo.php了。

三、优化php-fpm和fastcgi_params配置信息

PHP-FPM的配置文件在/usr/local/php/etc/php-fpm.conf中,下面对常用的配置项进行说明:

<!-- 用来配置FastCGI进程监听的IP地址以及端口,默认为127.0.0.1:9000 -->
 <value name="listen_address">127.0.0.1:9000</value>
 <!-- 用来配置是否显示PHP错误信息,默认是0不显示,设置为1显示信息 -->
 <value name="display_errors">0</value>
 <!-- 用来设置运行FastCGI进程的用户和用户组。这里指定的用户和用户组必须和Nginx配置文件中指定的一致。 -->
 <value name="user">www</value><value name="group">www</value>
 <!-- 用于设置FastCGI的进程数。根据官方建议,小于2G内存的服务器可以只开启64个进程,4GB以上内存服务器可以开始256个进程。 -->
 <value name="max_children">128</value>
 <!-- 执行脚本的时间,默认为0表示无限执行下去。 -->
 <value name="request_terminate_timeout">0s</value>
 <!-- 设置PHP-FPM对打开文件描述符的限制,默认为1024。该值必须和Linux内核打开文件数关联起来,
      如将该值设置为65535就必须在Linux命令行中执行 ulimit -HSn 65535。 -->
 <value name="rlimit_files">65535</value>
 <!-- 设定每个children最多处理多少个请求后便会自动关闭,默认设置为500。 -->
 <value name="max_requests">1024</value>
 <!-- 设置允许访问FastCGI进程解析器的IP地址,如果不在这里指定IP地址,将无法接受Nginx转发过来的PHP解析请求。 -->
 <value name="allowed_clients">127.0.0.1</value>

fastcgi_param配置文件在 /usr/local/nginx/conf/fastcgi_params中,将其中的fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;中$nginx_version去掉,隐藏nginx的版本。

#fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  SERVER_SOFTWARE    nginx;

四、常见错误及解决方法

首先说明一下,如果nginx启动之后,无法访问网站或者访问有错误,这个时候应该第一时间查看nginx(默认在nginx安装目录的logs文件夹下)或php-fpm(默认在php根目录的logs/php-fpm.log文件中)的日志文件,里面有详细的错误信息。

1. 当访问php文件的时候页面出现“No input file specified”提示,而静态文件则正常。
这个是因为在站点设置中对php扩展的解析里面,fastcgi_param SCRIPT_FILENAME 后面的路径出现错误,使得php-fpm无法找到php文件,解决的方法是将$fastcgi_script_name前面的路径设置成网站根目录的绝对路径即可,注意路径最后没有斜杠/,即:

fastcgi_param SCRIPT_FILENAME /www/piaoyun.cc$fastcgi_script_name;

看到有的网站上面还提到需要将php.ini文件中的cgi.fix_pathinfo项设置为1,但是我没有进行设置也是好的,估计是nginx的版本不同。

2. [ERROR] fpm_unix_conf_wp(), line 124: please specify user and group other than root, pool 'default'
上面的错误是在php-fpm.log日志文件中出现的,原因是没有设置php-fpm的用户和用户组,或者没有将php-fpm的用户或用户组修改成与nginx的一样。解决方法是修改php-fpm.conf配置文件中user和group,默认情况下这两项配置是被注释的。

<value name="user">www</value>
<value name="group">www</value>

3. [error] 19075#0: *4 connect() failed (110: Connection timed out) while connecting to upstream, ......
这个错误提示是告诉我们nginx转发到php-fpm的时候连接超时了,所以如果访问量太大的话可以将超时的时间设置长一些。但如果网站访问量不大或者刚开始配置之后就出现这个错误的话,往往是iptables设置的问题。验证的方法是:如果将iptables停止(/etc/init.d/iptables stop)之后访问正常则说明是防火墙配置的问题,在防火墙中增加如下规则即可:

iptables -I INPUT 2 -i lo -p all -j ACCEPT
/etc/init.d/iptables save
/etc/init.d/iptables start

4. 启动nginx的时候出现 [emerg]: getpwnam("www") failed 错误
这个错误中getpwnam中间的www可能是其他的名称,主要原因是编译nginx和nginx配置文件(nginx.conf)中设置的用户和用户组不存在,所以只要创建对应的用户和用户组即可。

5. [emerg] 30558#0: setuid(500) failed (11: Resource temporarily unavailable)
错误信息中的setuid中间的数字肯是其他数字,比如501、502等等。这个错误需要一步一步的进行排查,相对有点复杂,解决的方法如下:
首先根据setuid中间的数字查看对应数字的用户是否存在,如果不存在则创建用户:

more /etc/passwd | grep 500
# 如果没有任何信息显示则查看nginx配置文件中指定的用户名称,然后使用useradd创建该用户并指定用户组

如果用户存在的话,则使用 ulimit -n 命令查看服务器文件描述符是多少,默认是1024,然后使用 ps -U www | wc -l 命令查看www用户所启用的进程数量(注意将www用户换成你自己的),如果显示的数量超过了服务器文件描述符的数量,则需要提升该参数,具体的做法是:将nginx.conf中的worker_rlimit_nofile、worker_connections和php-fpm.conf文件中的rlimit_files配置项设置大一些,也可以直接设置成65535(最大值)。然后还需要加大服务器文件描述符的大小。有两种设置方法:

# 一种是修改/etc/security/limits.conf文件,然后重启服务器
echo '* - nofile 65535' >> /etc/security/limits.conf
# 另外一种是使用 ulimit -HSn 65535 命令,将该命令添加到开机启动并放在php-fpm和nginx启动前
ulimit -HSn 65535
cat >> /etc/rc.local <<EOF
/etc/init.d/mysql start
ulimit -SHn 65535
/usr/local/php/sbin/php-fpm start
/usr/local/nginx/sbin/nginx
EOF

一定要确认“ulimit -HSn ”后面的数字需要和nginx.conf中的worker_rlimit_nofile、worker_connections和php-fpm.conf文件中的rlimit_files配置项设置成相同的数字。

如果安装上面的设置修改之后还有错误的话,恭喜你,你的人品大大的提升了,这种情况是比较少见的,先确认一下你是否进行了重启,如果重启过了还可以将 “ulimit -SHn 65535” 命令添加到/etc/profile 中:

echo "ulimit -SHn 65535" >> /etc/profile

一、nginx的几个命令参数
Nginx 安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对 Nginx 进程本身进行控制的。 Nginx 的参数包括有如下几个:

可以这样使用:

/usr/local/nginx/sbin/nginx -参数

-c <path_to_config>:使用指定的配置文件而不是 conf 目录下的 nginx.conf 。
-t:测试配置文件是否正确,在运行时需要重新加载配置的时候,此命令非常重要,用来检测所修改的配置文件是否有语法错误。
-v:显示 nginx 版本号。
-V:显示 nginx 的版本号以及编译环境信息以及编译时的参数。

二、检测新的conf文件

测试当请目录下nginx.conf文件是否正确,使用命令:

nginx -t -c nginx.conf

2009/01/01 22:17:57 [info] 54240#0: the configuration file nginx.conf syntax is ok
2009/01/01 22:17:57 [info] 54240#0: the configuration file nginx.conf was tested successfully

得到如此结果,说明新conf文件没有错误。

如果有错,他会提示你在哪行出了错,在修改错误就可以了。

在nginx/conf/vhost/站点名称.conf 里的server段里面,添加如下的代码:(红色部分)

server
{
listen 80;
server_name www.piaoyun.cc piaoyun.cc;
if ($host != 'www.piaoyun.cc')
{
rewrite ^/(.*)$ http://www.piaoyun.cc/$1 permanent;
}

意思是:如果访问的域名来路不是www.piaoyun.cc就全部301跳转到带有www.piaoyun.cc的域名下面!

然后service nginx restart

第一种情况:访问A站定向到B站

server {
server_name A.com ;
rewrite ^(.*) http://www.A.com$1 permanent;
}

目前是使用此方法,第一部分的server取消上面的域名绑定!这个放在配置文件的最后!

第二种情况:不是访问A站的全部重定向到指定页面

server {
server_name www.A.com;
if ($host != ‘A.com’ ) {
rewrite ^/(.*)$ http://www.B.com/$1 permanent;
}
}

如果写在第一个server段
使用IP访问时也将被重定向

很多朋友问我,为什么他已经在apache规则里面加了禁止别人直接下载.htaccess文件,为什么还是可以下载!
其实这个很简单,因为.htaccess在lnmpa当它作为文件被访问的时候其实是由Nginx来处理的,所以我们需要在Nginx里来添加规则.

而且这个规则,在Nginx默认的里面是存在的。

# deny access to .htaccess files, if Apache’s document root
# concurs with nginx’s one
location ~ /\.ht {
deny all;
}

复制到你的nginx/conf/vhost/站点名称.conf 里,然后service nginx restart

nginx禁止访问所有.开头的隐藏文件设置

location ~* /\.* {
deny all;
}

nginx禁止访问目录,例如:禁止访问path目录

location ^~ /path {
deny all;
}

可以把path换成实际需要的目录,目录path后是否带有"/",带"/"只禁止访问目录,不带"/"禁止访问目录中的文件
注意这段禁止php权限的secion一定要放在 指定的php section的前面才可以生效的.
禁止多个目录的php执行访问权限和html文件的访问!

location ~ /(upload|cache/templates)/.*\.(php|php5|html)?$
{
deny all;
}

博客目前用的独立ip,如果某些别有用心的人用未备案的域名解析我的ip到我博客,一会gfw发作,把我ip封了就欲哭无泪了。因此需要将没有绑定的域名制止访问或跳转到其他页面。可以用下面的方法实现。

看了很多Nginx的配置,好像都忽略了ip直接访问Web的问题,这样理论上不利于SEO优化,所以我们希望可以避免直接用IP访问网站,而是域名访问,具体怎么做呢,看下面。

官方文档中提供的方法:
If you do not want to process requests with undefined "Host" header lines, you may define a default server that just drops the requests:

server {
listen 80 default_server;
server_name _;
return 500;
}

后面的default参数表示这个是默认虚拟主机。Nginx 禁止IP访问这个设置非常有用。
说白了就是只要是访客用ip访问就直接500错误。但是这样好像又不太友好,如果能直接给跳转到该web server的网址就好了。配置如下:

server {
listen 80 default_server;
server_name _;
rewrite ^ http://www.piaoyun.cc$request_uri?;
}
server {          // 该段server主要就是防止别人恶意解析域名到我们的IP地址,这样直接跳转到我们自己的网站.
listen         80  default_server;
server_name _;
rewrite  ^/(.*) http://piaoyun.cc/$1 permanent;
}

这样还是有一点问题,某些特别的地址,我需要用ip访问,其他的都禁止,如何配置呢?比如说我想让监控宝直接用ip访问我的机器的nginx状态信息,其他的用ip访问的所有请求都跳转到域名上。

server {
listen 80 default_server;
server_name _;
location /xxxxx{
stub_status on;
access_log off;
}
location /{
rewrite ^ http://www.piaoyun.cc$request_uri?;
}
}

用 Nginx -t 来检测配置文件!

另外,在这里说一下server_name。server_name 是可以使用正则表达式的,这个功能因该说相当实用。

Nginx中的server_name指令主要用于配置基于名称的虚拟主机,server_name指令在接到请求后的匹配顺序分别为:

1、准确的server_name匹配,例如:

server {
listen 80;
server_name domain.com www.domain.com;
...
}

2、以*通配符开始的字符串:

server {
listen 80;
server_name *.domain.com; ...
}

3、以*通配符结束的字符串:

server {
listen 80;
server_name www.*;
...
}

4、匹配正则表达式:

server {
listen 80;
server_name ~^(?.+)\.domain\.com$; ...
}

nginx将按照1,2,3,4的顺序对server name进行匹配,只有有一项匹配以后就会停止搜索,所以我们在使用这个指令的时候一定要分清楚它的匹配顺序(类似于location指令)。

server_name指令一项很实用的功能便是可以在使用正则表达式的捕获功能,这样可以尽量精简配置文件,毕竟太长的配置文件日常维护也很不方便。下面是2个具体的应用:
1、在一个server块中配置多个站点:

server
{
listen 80;
server_name ~^(www\.)?(.+)$;
index index.php index.html;
root /data/wwwsite/$2;
}

站点的主目录应该类似于这样的结构:
/data/wwwsite/domain.com
/data/wwwsite/nginx.org
/data/wwwsite/baidu.com
/data/wwwsite/google.com

这样就可以只使用一个server块来完成多个站点的配置。

2、在一个server块中为一个站点配置多个二级域名。
实际网站目录结构中我们通常会为站点的二级域名独立创建一个目录,同样我们可以使用正则的捕获来实现在一个server块中配置多个二级域名:

server
{
listen 80;
server_name ~^(.+)?\.domain\.com$; index index.html;
if ($host = domain.com){ rewrite ^ http://www.domain.com permanent; }
root /data/wwwsite/domain.com/$1/; }

站点的目录结构应该如下:

/data/wwwsite/domain.com/www//data/wwwsite/domain.com/nginx/
这样访问www.domain.com时root目录为/data/wwwsite/domain.com/www/,nginx.domain.com时为/data/wwwsite/domain.com/nginx/,以此类推。

后面if语句的作用是将domain.com的方位重定向到www.domain.com,这样既解决了网站的主目录访问,又可以增加seo中对www.domain.com的域名权重。

什么是SSI?
SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针。SSI具有强大的功能,只要使用一条简单的SSI命令就可以实现整个网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。

include的是使用方法如下:红色部分是引用的文件路径!
<!--#include file="1.html" -->
<!--#include virtual="/piaoyun/html/1.html" -->

示例
<!--被包含文件与父文件存在于相同目录中。-->
<!--#include file="1.html" -->

<!--被包含文件位于脚本虚拟目录中。 -->
<!--#include virtual="/piaoyun/html/1.html" -->

include file 与include virtual的区别:
1.#include file 包含文件的相对路径,#include virtual包含文件的虚拟路径。

2. 在同一个虚拟目录内,<!--#include file="1.html"-->和<!--#include virtual="1.html"-->效果是相同的,但假设虚拟目录名为piaoyun,则<!--#include virtual="piaoyun/file.html"-->也可以通过调试,但我们知道<!--#include file="piaoyun/file.html"-->是绝对要报错的。

3.如果一个站点下有2个虚拟目录piaoyun1和 piaoyun2,piaoyun1下有文件file1.html,piaoyun2下有文件file2.html,如果file1.html要调用 file2.html,那么在file1.html中要这样写:<!--#include virtual="piaoyun2/file2.html"-->,在这种情况下用#include file是无法实现的,用<!--#include file="piaoyun2/file2.html"-->必然报错。相反,在piaoyun2的文件中包含piaoyun1中的文件也是一样。 如果该被包含文件在某个文件夹下面,只要在虚拟路径中加上该文件夹即可。

4.不论用#include file 还是 #include virtual,在路径中用“/”还是“/”或者二者交叉使用都不会影响编译效果,程序会顺利执行。

5. 以上情况不适用于2个站点文件的相互调用,而且在同一个站点内,<!--#include file="file.html"-->和<!--#include virtual="file.html"-->等效,但假设站点名为website,使用<!--#include virtual="website/file.html"-->是错误的。

nginx 内置了ssi模块,开启方法
修改 nginx 的配置文件

# vi /usr/local/nginx/conf/nginx.conf

在http{}中添加如下代码即可:
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;
ssi_types text/htm;

ps.这里文件类型可以改成其他的,比如让htm也支持ssi,那么把text/shtml改成text/htm就行了,但是这样的话,由于服务器里htm的文件较多,也不一定全都用ssi引入其他页面,会给nginx造成一些不必要的消耗,所以不建议这么做。

在nginx.conf 的http里面加入如下四行(绿色部分的代码)
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;
ssi_types text/htm;
server
{
listen 80;
server_name www.piaoyun.org;
index index.shtml;

apache下的配置方法:

如何使你的Apache服务器支持SSI?
1. 确认加载include.so模块,将注释去掉:
LoadModule include_module modules/mod_include.so

2. AddType部分去掉这两段注释:
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

3. Directory目录权限里面找到
Options Indexes FollowSymLinks
增加Includes修改为:
Options Indexes FollowSymLinks Includes ExecCGI MultiViews
PS:这里的ExecCGI是因为我本机的apache是以FastCGI方式加载的,所以要添加这个!

具体的安装配置方法如下:
Windows7 64位系统下面配置Apache2.2+PHP5.3+mod_fcgid运行高效的FastCGI模式安装方法
http://piaoyun.cc/windows7-apache-fastcgi-mod-fcgid.html
4. 重新启动Apache,测试:
<!--#include file=head.html”-->
Holle Word!,这是中间的内容
<!--#include file=foot.html”-->
方法一:
添加 SSI 页面的新句柄,缺省情况下,Apache 即使在需要时也不对 HTML 文件进行解析。假如将 .shtml 作为所有包含一个或多个 SSI 指令的 HTML 页面的 SSI 文件扩展名,需要告诉 Apache 将 .shtml 文件扩展名视为需要进行 SSI 解析的页面。如果因为某些原因,将 .html 和 .htm 用做 SSI 扩展名,该这样使用:
AddHandler server-parsed .html
AddType text/html .html
AddHandler server-parsed .htm
AddType text/html .htm

方法二:
添加如下信息:
AddType text/html .ssi
AddOutputFilterByType INCLUDES;DEFLATE text/html
然后保存httpd.conf,重启apache。
如果开启了虚拟主机配置文件的话,也要在相对应的虚拟主机配置文件添加如下内容:

虚拟主机配置方式:(红色部分的内容)

<VirtualHost *:60>
ServerAdmin webmaster@phpcms
DocumentRoot "D:/wwwroot/piaoyun.cc"
ServerName piaoyun.org
ErrorLog "logs/dummy-piaoyun.cc-error.log"
CustomLog "logs/dummy-piaoyun.cc-access.log" common
<Directory />
Options Indexes FollowSymLinks Includes ExecCGI MultiViews
AllowOverride All
Order deny,allow
allow from all
</Directory>
<IfModule mime_module>
AddHandler server-parsed .html
AddType text/html .html
AddHandler server-parsed .htm
AddType text/html .htm
AddHandler server-parsed .php
AddType text/html .php
</IfModule>
</VirtualHost>

如果让php也支持SSI语句,可以在虚拟机配置和httpd.conf里面都加上一行,AddOutputFilter Includes .php,如下:

<Directory />
Options Indexes FollowSymLinks Includes
AllowOverride None
AddOutputFilter Includes .php
</Directory>

保存后,重起apache即可。
PS:我在本地按照这个方法设置,PHP始终是不支持includes呢,求各位大神的解决办法!如果有好的解决办法,请在博文后给我留言!
写在最后的话:
如果你在windows下安装有mod_gzip.so模块的话,这个会和ssi与include起冲突,取消就可以了!

504 Gateway Time-out问题常见于使用nginx作为web server的服务器的网站

我遇到这个问题是在升级discuz论坛的时候遇到的!

一般看来, 这种情况可能是由于nginx默认的fastcgi进程响应的缓冲区太小造成的, 这将导致fastcgi进程被挂起, 如果你的fastcgi服务对这个挂起处理的不好, 那么最后就极有可能导致504 Gateway Time-out
现在的网站, 尤其某些论坛有大量的回复和很多内容的, 一个页面甚至有几百K
默认的fastcgi进程响应的缓冲区是8K, 我们可以设置大点
在nginx.conf里, 加入:

fastcgi_buffers 8 128k

这表示设置fastcgi缓冲区为8×128k
当然如果您在进行某一项即时的操作, 可能需要nginx的超时参数调大点, 例如设置成60秒:

send_timeout 60;

我只是调整了这两个参数, 结果就是没有再显示那个超时, 可以说效果不错, 但是也可能是由于其他的原因, 目前关于nginx的资料不是很多, 很多事情都需要长期的经验累计才有结果, 期待您的发现哈!