nginx的配置文件详解
worker_processes 24;
#指定工作衍生进程数,(一般等于CPU的总核数或者总核数的两倍,例如两个4核CPU,总核数为8)
#指定错误日志的存放路径和错误日志级别:[debug|info|notice|warn|error|crit]
worker_rlimit_nofile 51200#指定文件描述符数量
event{ use epoll}#linux 下默认的I/O网络模型,默认采用的是epoll模型。
worker_connections 65535;#允许的连接数
client_max_body_size 8m#设置客户端能够上传的文件的大小
#开启gzip压缩功能
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#写个判断机制
if ($request_uri ~* ^.*\.svn.*$) {
return 404;
}
if ($request_filename !~ (/index.php/jsapi|/fonts|/javascript) ) {
rewrite ^/(.*)$ /index.php/user/$1 last;
break;
}
#域名重定向链接
server {
listen 80;
server_name ftchinese.com;
rewrite ^/(.*) http://www.ftchinese.com/$1 permanent;
}
#对于每一条日志记录,日志文件都将先打开文件,再写入日志记录,然后马上关闭,为了提高包含变量的日志文件存放路径的性能,需用open_log_file_cache指令设置经常被使用的日志文件描述符缓存。
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time] | off 该指令默认是禁止的
open_log_file_cache off
lnmp环境的配置和优化:
提高PHP(FastCGI),什么是FastCGI呢?
FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获取较高的性能。总所周知,CGI解释器的反复加载是CGI
性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理调度,则可以提供良好的性能、伸缩性、Fail-Over特性等。
FastCGI的工作原理是:
(1)、FastCGI进程管理自身初始化,启动多个CGI解释器进程(多个php-cgi进程)并等待来自Web Server的链接。在本文中,采用PHP-FPM进程管理器启动多个php-cgi FastCGI进程。启动php-cgi FastCGI进程时,可以配置以TCP和UNIX套接字两种方式启动。
(2)、当客户端请求到达Web服务器时,web服务器将请求采用TCP协议或者UNIX套接字方式转发到FastCGI主进程,FastCGI主进程选择并连接到一个CGI解释器(子进程)。web服务器将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
(3)、FastCGI进程完成处理后将标准输出和错误信息从同一连接返回web服务器。当FastCGI子进程关闭连接时,请求便告知处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器的下一个连接。而在一般的普通CGI模式中,php-cgi在此时已经退出了。
所以可以想象普通的CGI模式到底有多慢。每一个web请求PHP都必须重新解析php.ini、重新载入全部扩展并重新初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外好处是:持续数据库连接可以工作。
nginx负载均衡的主要模块之HTTP Upstream模块
Upstream模块是nginx负载均衡的主要模块,它提供了一个简单的方法来实现在轮询和客户端IP之间的后端服务器负载均衡,并可以对后端服务器进行健康检查。
ip_hash指令
语法:ip_hash
默认值:None
使用环境:Upstream
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台服务器上。这样,当来自某个IP的用户在后端web服务器A上登录后,再访问该站点的其他URL,能保证其访问的还是后端web服务器A。如果不采用IP_hash指令,假设来自某个ip的用户在后端web服务器A上登录后,再访问该站点的其他URL,有可能被定向到后端Web服务器B,C...上,由于用户登录后session信息记录在服务器A上的,B,C...上没有,这时就会提示用户未登录。
使用ip_hash指令无法保证后端服务器的负载均衡,可能有些后端服务器接收到的请求多,有些后端服务器接收到的请求少,而且设置后端服务器权重等方法将不起作用。所以,如果后端的动态应用服务器能够做到session共享,还是建议采用后端服务器的session共享方式来代替nginx的ip_hash方式。
如果后端服务器有时要从nginx负载均衡(已使用ip_hash)中摘除一段时间,你必须将其标记为“down”,而不是直接从配置文件中删除或者注释掉该后端服务器的信息。
upstream backend{
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;#当原来为4台服务器时,3标记为down后,nginx仍然会按4台服务器进行哈希。如果直接注释掉,nginx会按照3台服务器进行重新哈希,原来哈希到server1 上的ip地址可能被哈希到server2上边,原来的session就会失效。
server backend4.example.com
}
server指令
server
语法:servername[parameters]
默认值:none
使用环境:upstream
该指令用于指定后端服务器的名称和参数。服务器的名称可以是一个域名、一个ip地址、端口号或UNIX Socket。
在后端服务器名称之后,可以跟以下参数:
a、weight=NUMBER---设置服务器的权重,权重数值越高,被分配到的客户端请求数越多。如果没有权重,则为默认值权重1
b、max_fails=NUMBER---在参数fail_timeout指定的时间内对后端服务器请求失败的次数,如果检测到后端服务器无法连接或者发生服务器错误(404除外),则标记为失败。如果没有设置,则默认值为1,设为数值0将关闭这项检查。
c、fail_timeout=TIME---在经历参数max_fails设置的失败次数后,暂停的时间
d、down---标记服务器为永久离线状态,用于ip_hash指令
e、backup---仅仅在非backup服务器全部宕机或者繁忙的时候才启用。
upstream backend{
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream 指令
语法:upstream name{...}
默认值:none
使用环境:http
该指令用于设置一组可以在proxy_pass和fastcgi_pass指令中使用的代理服务器,默认的负载均衡方式为轮询。示例如下:
upstream backend{
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream相关变量
log_format timing '$remote_addr - $remote_user [$time_local] $request '
' upstream_response_time $upstream_response_time'
'msec $msec request_time $request_time';
log_format up_head '$remote_addr - $remote_user [$time_local] $request '
' upstream_http_content_type $upstream_http_content_type' ;
upstream模块拥有以下的变量:
$upstream_addr
处理请求的upstream服务器地址
$upstream_status
upstream服务器的应答状态
$upstream_response_time
upstream服务器响应时间(毫秒),多个响应以逗号和冒号分割
$upstream_http_$HEADER
任意的HTTP协议头信息。如:$upstream_http_host
nginx负载均衡服务器的双机高可用
第一种方式:
(1)、www.youedomain.com域名解析到虚拟IP 61.1.1.2上。
(2)、正常情况下,主机61.1.1.4绑定虚拟IP61.1.1.2
/sbin/ifconfig eth0:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.2 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1
(3)、用户访问www.youedomain.com(虚拟ip61.1.1.2)实际访问的是主机61.1.1.4.而备机61.1.1.5则处于空闲状态
(4)、如果主机61.1.1.4发送故障,备机61.1.1.5将在几秒钟之内接管虚拟ip61.1.1.2,与自己绑定,并发送ARPing包给IDC的公网网关刷新MAC地址。
/sbin/ifconfig eth0:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.2 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1
(5)、这时,用户访问www.youedomain.com(虚拟ip地址为61.1.1.2)实际上访问的是备机61.1.1.5,从而实现故障转移与高可用,避免了单点故障。
注意:此种方式还可以利用基于VRRP路由协议的Keepalived软件来实现。
第二种方式:
(1)、www.yourdomain.com域名通过DNS轮询解析到虚拟IP61.1.1.3和61.1.1.3上
(2)、正常情况下,server1 61.1.1.4绑定虚拟ip61.1.1.2,server261.1.1.5绑定虚拟IP地址61.1.1.3.
(3)、在server1上执行如下命令:
/sbin/ifconfig eth0:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.2 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1
(4)、在server2上执行以下命令:
/sbin/ifconfig eth0:1 61.1.1.3 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.3 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1
(5)、用户访问www.yourdomain.com(虚拟ip地址为61.1.1.2和61.1.1.3)实际上是根据DNS轮询访问两天负载均衡服务器,两台服务器均处于活的状态。
(6)、如果server1发生故障,server2将在几秒钟之内接管server1的虚拟ip61.1.1.2,与自己绑定,并发送ARPing包给IDC的公网网关刷新MAC地址,server2同时绑定61.1.1.2和61.1.1.3两个虚拟ip
(7)、在server2上执行如下命令:
/sbin/ifconfig eth0:1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
/sbin/route add -host 61.1.1.2 dev eth0:1
/sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1
nginx的Rewrite规则与实例
rewrite主要的功能就是实现url的重写,nginx的rewrite规则采用PCRE,Perl兼容正则表达式的语法进行规则匹配,如果您需要nginx的rewrite功能,在编译nginx之前,必须编译安装pcre库。
rewrite的应用:通过rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。例如:
一些使用MVC框架的程序只有一个入口,可以通过rewrite来实现。一些动态URL地址需要伪装成静态HTML。便于搜索引擎抓取,也需要rewrite来处理。一些用于目录结构、域名变化的旧URL,也必须跳转到新的URL上,也可以通过rewrite来处理。
rewrite指令的最后一项参数为flag标记,支持的flag标记主要有以下几种:
a、 last :相当于Apache里德(L)标记,表示完成rewrite;
b、 break;本条规则匹配完成后,终止匹配,不再匹配后面的规则
c、 redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
d、 permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
e、 last和break用来实现URL重写,浏览器地址栏URL地址不变
nginx rewrite规则相关指令有if、rewrite、set 、return、break等,其中rewrite是最关键的指令。
break指令
语法:break
默认值:none
使用环境:server,location,if
该指令的作用是完成当前的规则集,不再处理rewrite指令
示例如下:
if ($slow) {
limit_rate 10k;
break
}
if指令
语法:if(condition){...}
默认值:none
使用环境:server,location
该指令用于检查一个条件是否符合,如果条件符合,则执行大括号内的语句。if指令不支持嵌套,不支持多个条件&&和||处理。
以下信息可以被指定为条件:
(1)变量名:错误的值包括:空字符串"",或者任何以0开始的字符串;
(2)变量比较可以使用"="(表示等于)和"!="(表示不等于)运算符;
(3)正则表达式模式匹配可以使用"~*"和"~"符号;
(4)“~”符号表示区分大小写字母的匹配;
(5)"~*"符号表示不区分大小写字母的匹配(例如firefox与FireFox是匹配的);
(6)“!~”和“!~*”符号的作用刚好和"~"、"!~*"相反,表示不匹配;
(7)"-f"和"!-f"用来判断文件是否存在;
(8)"-d"和"!-d"用来判断目录是否存在;
(9)"-e"和"!-e"用来判断文件或目录是否存在;
(10)"-x"和"!-x"用来判断文件是否可执行。
部分正则表达式可以在圆括号"()"内,其值可以通过后面的变量$1至$9访问,示例:
if ($http_user_agent ~MSIE) {
rewrite ^(.*)$ /mise/$1 break;
}
return指令
语法:return code
默认值:none
使用环境:server,location,if
该指令用于结束规则的执行并返回状态码给客户端。状态码可以这些值:204,400,402~406,408,410,411,413,416及500~504。此外,非标准状态码444将以不发送任何Header头的方式结束连接。
注意:某些代理服务器在DNS查询超时时会返回400或者500的错误.
rewrite指令
语法:rewrite regex replacement flag
默认值:none
使用环境:server,location,if
该指令根据表达式来重定向URI,或者修改字符串。指令根据配置文件中的顺序来执行。
注意:重写表达式只对相对路径有效。如果你想配对主机名,你应该使用if语句,代码如下:
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;#$1contains '/foo',not 'www.mydomain.com/foo'
}
如果替换串以http://开头,将会采用301或302跳转进行URL重定向
在以上的标记中,last和break用来实现URI重写,浏览器地址栏的URL地址不变,但在服务器访问的路径发生了变化。redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址。
last和break标记的实现功能类似,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记。last标记在本条rewrite规则执行完毕后,会对其所在的server[......]标签重新发起请求,而break标记则在本条规则匹配完成后,终止匹配,不再匹配后面的规则。如下:必须使用break标记,使用last会导致死循环:
location /cms/{
proxy_pass http://test.yourdomain.com;
rewrite "^/cms/(.*)\.html$" /cms/index.html break;
}
因此,一般在根location中(即location /{...})或直接在server标签中编写rewrite规则,推荐使用last标记,在非根location中(例如:location /cms/{...}),
则使用break标记。如:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
location /download {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
如果被替换的URI中含有参数(即类似/app/test.php?if=5之类的URI),默认情况下参数会被自动附加到替换串上,你可以通过在替换串的末尾加上?标记来解决这一问题。
rewrite ^/users/(.*)$ /show?user=$1? last;
下面我们来比较一下,不加?标记和加上?标记的URL跳转区别:
rewrite ^/test(.*)$ http://www.yourdomain.com/home permanent;
访问http://www.yourdomain.com/home/test?id=5 经过301跳转后的URL地址为:http://www.yourdomain.com/home?id=5
rewrite ^/test(.*)$ http://www.yourdomain.com/home? permanent;
访问http://www.yourdomain.com/home/test?id=5经过301跳转后的URL地址为http://www.yourdomain.com/home
注意:对于({和})来说,他们既能用在重定向的正则表达式里,也能用在配置文件里分割代码块,为了避免冲突,正则表达式里如果带花括号,应该用双引号(会在单引号)包围。如下:
/photos/123456
重定向到:
/path/photos/12/1234/123456.png
可以用以下方法(注意双引号):
rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})"
/path/to/photos/$1/$1$2/$1$2$3.png;
set指令
语法:set variable value
默认值:none
使用环境:server,location,if
该指令用于定义一个变量,并给变量赋值。变量的值可以是文本、变量及文本变量的联合。
示例:
set $varname 'hello';
uninitialized_variable_warn 指令
语法:uninitialized_variable_warn on|off
默认值:uninitialized_variable_warn on
使用环境:http,server,location,if
该指令用于开启或关闭记录关于未初始化变量的警告信息,默认值为开启。
nginx的rewrite规则编写示例:
文件和目录不存在时,重定向到某个PHP文件上。适用于WordPress 等MVC结构的开源博客系统:
#-e filename 如果 filename存在,则为真
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php last;
}
多目录转成参数 abc.domain.com/sort/2 =>abc.domain.com/index.php?act=sort&name=abc&id=2:
if ($host ~* (.*)\.domain\.com) {
set $sub_name $1;
rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
}
目录对换 /123456/xxxx ->/xxxx?id=123456:
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
如果客户端使用IE浏览器,则重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
禁止访问多个目录:
location ~^/(cron|templates)/{
deny all;
break;
}
禁止访问以/data开头的文件:
location ~^/data {
deny all;
}
设置某些类型文件的浏览器缓存时间:
location ~ .*\.(gif|jpg|jpeg|pnf|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
将多级目录下的文件转换成一个文件/job-1234-456-789.html指向job/123/456/789.html:
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
禁止访问以.sh 、 .flv 、 .mp4为文件名后缀的URL地址:
location ~ .*\.(sh|flv|mp4)?$ {return 403;}
由以上示例可以看出,Apache的rewrite规则改为nginx的rewrite规则,其实很简单:Apache的rewriterule指令转换成nginx的rewrite指令,Apache的[L]标记换成nginx的last标记,中间的内容不变。
如果Apache的rewrite规则改为nginx的rewrite规则后,使用nginx -t命令检查发现nginx.conf配置文件有语法错误(主要是大括号引起的),那么可以尝试给条件加上引号。如下为错误:
rewrite ^/([0-9]{5}).html$ /x.jsp?id=$1 last;
加上引号就正确了:
rewrite "^/([0-9]{5}).html$" /x.jsp?id=$1 last;
apache 与nginx的rewrite规则在URL跳转时有细微的区别:
Apache rewrite的规则,如下:
RewriteRule ^/html/tagindex/([a-zA-Z])/.*$/$1/ [R=301,L]
nginx 的规则:
rewrite ^/html/tagindex/([a-zA-Z]+)/.$ http://$host/$1 permanent;
Apache与nginx的rewrite规则在变量名称方面也有区别。
介绍:Apache和nginx rewrite规则的一些功能相同或者类似的指令、标记对应关系
Apache的RewriteCond指令对应nginx的if指令
Apache的RewriteRule指令对应nginx的rewrite指令;
Apache的[R]标记对应nginx的redirect标记
Apache的[P]标记对应nginx的last标记
Apache的[R,L]标记对应nginx的redirect标记;
Apache的[P,L]标记对应nginx的last标记;
Apache的[PT,L]标记对应nginx的last标记;
nginx的web缓存服务
nginx的web缓存服务器主要有proxy_cache相关指令集和fastCGI相关指令集构成,前者用于反向代理时,对后端内容源服务器进行缓存,后者主要用于对fastCGI的动态程序进行缓存。
proxy_cache相关指令集
1、proxy_cache指令
语法:proxy_cache zone_name;
默认值:None
使用环境:http,server,location
该指令用于设置哪个缓存区将被使用,zone_name值为proxy_cache_path指令创建的缓存区的名称。
2、proxy_cache_path
语法:proxy_cache_path path[level=number] keys_zone=zone_name:zone_size[inactive=time] [max_size=size]
默认值:None
使用环境:http
该指令用于设置缓存文件的存放路径:示例如下:
proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one: 500m inactive=1d max_size=30g;
注意:该指令只能在http标签内配置,levels指定该缓存空间有两层目录,第一层目录为1个字母,第二层为2个字母,保存的文件名会类似/data0/proxy_cache/c28/brwvfege3454565555555-er4t54t5g5665c;keys_zone参数用来为这个缓存区起名,500m指内存缓存空间大小500MB;
inactive的1d指如果缓存数据在1天内没有被访问,将被删除;max_size的30g是指磁盘缓存空间为30G。
3、proxy_cache_methods指令
语法:proxy_cache_methods[GET HEAD POST]
默认值:proxy_cache_methods GET HEAD;
使用环境:http,server,location
该指令用于设置缓存那些http方法,默认缓存http get/head方法。不缓存http post 方法;
4、proxy_cache_min_uses指令
语法:proxy_cache_min_uses the_number;
默认值:proxy_cache_min_uses 1;
使用环境:http、server、location
该指令用于设置缓存的最小使用次数,默认为1
5、proxy_cache_valid指令
语法:proxy_cache_valid reply_code[reply_code...]time;
默认自:None
使用环境:http、server、location
该指令用于对不同返回状态码的URL设置不同的缓存时间,例如:
proxy_cache_valid 200 302 10m; #设置200,302状态的URL缓存10分钟
proxy_cache_valid 404 1m;#设置404的缓存时间为1分钟
proxy_cache_valid 5m;#如果不指定状态码,直接指定缓存时间,则只有200 301 302 状态的URL缓存5分钟。
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;#对没有单独设置的状态码,全部设置缓存时间为1分钟。
6、proxy_cache_key指令
语法:proxy_cache_key line;
默认值:None
使用环境:http,server,location
该指令用于设置web缓存的key值,nginx根据key值md5哈希存储缓存。一般根据$host(域名)、$request_uri(请求路径)等变量组合成proxy_cache_key。
如:proxy_cache_key "$host:$server_port$uri$is_args$args";
注意:通过ngx_cache_purge模块编译安装到nginx中,用来清除指定URL的缓存。