在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结。
一、nginx服务简介
Nginx是一个高性能的HTTP和反向代理服务器,也是一个 IMAP/POP3/SMTP代理服务器。Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。
使用 Nginx 前必须了解的事项:
1)目前官方 Nginx 并不支持 Windows,您只能在包括 Linux、UNIX、BSD 系统下安装和使用;
2)Nginx 本身只是一个 HTTP 和反向代理服务器,它无法像 Apache 一样通过安装各种模块来支持不同的页面脚本,例如 PHP、CGI 等;
3)Nginx 支持简单的负载均衡和容错;
4)支持作为基本 HTTP 服务器的功能,例如日志、压缩、Byte ranges、Chunked responses、SSL、虚拟主机等等,应有尽有。
Nginx工作原理:
Nginx由内核和一系列模块组成,内核提供web服务的基本功能,如启用网络协议,创建运行环境,接收和分配客户端请求,处理模块之间的交互。Nginx的各种功能和操作都由模块来实现。Nginx的模块从结构上分为核心模块、基础模块和第三方模块。
1)核心模块: HTTP模块、EVENT模块和MAIL模块
2)基础模块: HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块
3)第三方模块: HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用户自己开发的模块
这样的设计使Nginx方便开发和扩展,也正因此才使得Nginx功能如此强大。Nginx的模块默认编译进nginx中,如果需要增加或删除模块,需要重新编译Nginx,这一点不如Apache的动态加载模块方便。如果有需要动态加载模块,可以使用由淘宝网发起的web服务器Tengine,在nginx的基础上增加了很多高级特性,完全兼容Nginx,已被国内很多网站采用。
Nginx处理连接过程:
nginx不会为每个连接派生进程或线程,而是由 worker 进程通过监听共享套接字接受新请求,并且使用高效的循环来处理数千个连接。Nginx 不使用仲裁器或分发器来分发连接,这个工作由操作系统内核机制完成。监听套接字在启动时就完成初始化,worker 进程通过这些套接字接受、读取请求和输出响应。
Nginx的工作模式很简单,就是采用一个master进程和多个worker工作进程:
其中master进程的作用也是很明确的就是负责管理worker进程,同时监听连接请求,当连接请求到来之后将连接放入worker进程中去处理具体的业务请求,比如说http请求。 Nginx能够处理高并发的原因在于对socket的管理方式是异步非阻塞的,使用select/poll/epoll/kqueue 来实现对大量socket描述符的管理,每个worker进程有一个主线程,而没有其他的线程这样的好处就在于不需要进行线程间的切换,这样就节省了资源。所以总的来说:Nginx能够实现支持高并发的同时运行效率还很低的关键在于整个系统内部只有有限的几个工作进程和一个监听进程,而每个进程内部只有一个主线程,这样就不会引起很多的线程切换,从而降低了系统开销,同时每个线程内部使用异步非阻塞的方式来管理描述符这样就可以管理大量的描述符,当描述符多的时候也只是会占用较多的内存而已,而不会造成占用大量cpu时间。以上说的就是Nginx的进程模型和事件模型,事件模型中处理的情况主要有三种,分别是网络事件,如HTTP请求等,网络事件使用异步非阻塞模式就可以很好的解决;还有信号,定时器,信号和定时器还不是很明白。Nginx处理进程间争夺系统资源的方式:也就是进程间存在的惊群现象。
master:
当 nginx 在启动后,会有一个 master 进程和多个 worker 进程。master进程主要用来管理worker进程,master 要做的就是:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动重新启动新的 worker 进程。
主要完成如下工作:
1)读取并验证配置信息;
2)创建、绑定及关闭套接字;
3)启动、终止 worker 进程及维护 worker 进程的个数;
4)无须中止服务而重新配置工作;
5)控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本;
6)重新打开日志文件;
7)编译嵌入式perl脚本
worker:
对于基本的网络事件,则是放在 worker 进程中来处理了。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求(一对一)。然而 nginx 没有专门地仲裁或连接分布的 worker,这项工作是由操作系统内核机制完成的。在启动时,创建一组初始的监听套接字,HTTP 请求和响应之时,worker 连续接收、读取和写入套接字。
worker 进程主要完成的任务包括:
1)接收、传入并处理来自客户端的连接;
2)提供反向代理及过滤功能;
3)nginx任何能完成的其它任务
举例说明一个完整请求如何通过互相协作来实现的:
既然worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接。那么问题来了,到底最后怎样处理,是由什么决定的呢?首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,然后在读事件里调用 accept 接受该连接。当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。我们可以看到:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。
也许有个疑问,那就是nginx采用多worker 的方式来处理请求,每个 worker 里面只有一个主线程,那能够处理的并发数很有限啊,多少个 worker 就能处理多少个并发,何来高并发呢?
然而,这就是 nginx 的高明之处,nginx 采用了异步非阻塞的方式来处理请求,也就是说,nginx 是可以同时处理成千上万个请求的。
异步非阻塞
异步的概念是和同步相对的,也就是不同事件之间不是同时发生的。非阻塞的概念是和阻塞对应的,阻塞是事件按顺序执行,每一事件都要等待上一事件的完成,而非阻塞是如果事件没有准备好,这个事件可以直接返回,过一段时间再进行处理询问,这期间可以做其他事情。
二、nginx相对于传统的apache服务的优缺点
nginx相对比apache,实在有太多的优势。可以说,现在Nginx才是Web服务器的首选!!
1)nginx相对于apache的优点:
轻量级,同样起web 服务,比apache 占用更少的内存及资源;
抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能;
高度模块化的设计,编写模块相对简单;
社区活跃,各种高性能模块出品迅速;
当然apache相对于nginx也有它自身的优点:rewrite比nginx 的rewrite强大;模块超多,基本想到的都可以找到;少bug,nginx的bug相对较多;超稳定;apache有自带php解析功能(apache环境部署好后,不需要再启动php服务,apache自动解析php文件,机器上只要有php命令即可;但是nginx不行,nginx必须结合php服务才能解析php文件,两则服务都要启动)
存在就是理由,一般来说,需要性能的web 服务,用nginx 。
如果不需要性能只求稳定,那就用apache。
后者的各种功能模块实现得比前者,例如ssl 的模块就比前者好,可配置项多。
这里要注意一点,epoll(freebsd 上是 kqueue )网络IO 模型是nginx 处理性能高的根本理由,但并不是所有的情况下都是epoll 大获全胜的,如果本身提供静态服务的就只有寥寥几个文件,apache 的select 模型或许比epoll 更高性能。当然,这只是根据网络IO 模型的原理作的一个假设,真正的应用还是需要实测了再说的。
2)作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型.
Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多.
作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器), Last.fm 描述了成功并且美妙的使用经验.
Nginx 是一个安装非常的简单 , 配置文件非常简洁(还能够支持perl语法), Bugs 非常少的服务器: Nginx 启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够不间断服务的情况下进行软件版本的升级 .
3)Nginx 配置简洁,Apach复杂;Nginx静态处理性能比Apache高3倍以上;Apache对PHP支持比较简单,Nginx需要配合其他后端用;Apache的组件比Nginx多;
4)最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程
5)nginx处理静态文件好,耗费内存少.但apache目前也有它的优势,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式.
6)从个人过往的使用情况来看,nginx的负载能力比apache高很多。最新的服务器也改用nginx了。而且nginx改完配置能-t测试一下配置有没有问题,apache重启的时候发现配置出错了,会很崩溃,改的时候都会非常小心翼翼现在看有好多集群站,前端nginx抗并发,后端apache集群,配合的也不错。
7)nginx处理动态请求是鸡肋,一般动态请求要apache去做,nginx只适合静态和反向。
8)从个人经验来看,nginx是很不错的前端服务器,负载性能很好,linux服务器上运营nginx,用webbench模拟10000個个静态文件请求毫不吃力。apache对php等语言的支持很好,此外apache有強大的支持网路,反正时间相对nginx更久,bug少,但是apache有先天不支持多核心处理负载鸡肋的缺点,所以建议使用nginx做前端,后端用apache。大型网站建议用nginx自代的集群功能!
9)Nginx优于apache的主要两点还体现在:Nginx本身就是一个反向代理服务器;Nginx支持7层负载均衡;其他的当然,Nginx可能会比apache支持更高的并发;Aapche因为其成熟的技术和开发社区,总体来说也有非常不错的性能,很多大公司而言还比较青睐apache。
10)你对web server的需求决定你的选择。大部分情况下nginx都优于apache,比如说静态文件处理、PHP-CGI的支持、反向代理功能、前端Cache、维持连接等等。在Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出现Apache进程数飙升,从而拒绝服务的现象。
11)对于nginx,我喜欢它配置文件写的很简洁,正则配置让很多事情变得简单运行效率高,占用资源少,代理功能强大,很适合做前端响应服务器
12)Apache在处理动态有优势,Nginx并发性比较好,CPU内存占用低,如果rewrite频繁,那还是Apache更好。
三、在 Linux 下安装 Nginx
为了确保能在Nginx中使用正则表达式进行更灵活的配置,安装之前需要确定系统是否安装有PCRE(Perl Compatible Regular Expressions)包。
您可以到ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/下载最新的PCR 源码包,使用下面命令下载编译和安装 PCRE 包:
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.7.tar.gz
# tar zxvf pcre-7.7.tar.gz
# cd pcre-7.7
# ./configure
# make
# make install
接下来安装 Nginx,Nginx 一般有两个版本,分别是稳定版和开发版,您可以根据您的目的来选择这两个版本的其中一个,下面是把 Nginx 安装到 /opt/nginx 目录下的详细步骤:
# wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz
# tar zxvf nginx-0.6.31.tar.gz
# cd nginx-0.6.31
# ./configure --with-http_stub_status_module --prefix=/opt/nginx
# make
# make install
其中参数 --with-http_stub_status_module 是为了启用 nginx 的 NginxStatus 功能,用来监控 Nginx 的当前状态。
安装成功后/opt/nginx 目录下有四个子目录分别是:conf、html、logs、sbin 。
其中Nginx的配置文件存放于conf/nginx.conf,Nginx只有一个程序文件位于sbin目录下的nginx文件。
确保系统的80端口没被其他程序占用,运行sbin/nginx命令来启动Nginx,打开浏览器访问此机器的 IP,如果浏览器出现 Welcome to nginx! 则表示 Nginx 已经安装并运行成功。
常用的 Nginx 参数和控制
程序运行参数
Nginx 安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对 Nginx 进程本身进行控制的。 Nginx 的参数包括有如下几个:
-c <path_to_config>:使用指定的配置文件而不是 conf 目录下的 nginx.conf 。
-t:测试配置文件是否正确,在运行时需要重新加载配置的时候,此命令非常重要,用来检测所修改的配置文件是否有语法错误。
-v:显示 nginx 版本号。
-V:显示 nginx 的版本号以及编译环境信息以及编译时的参数。
例如我们要测试某个配置文件是否书写正确,我们可以使用以下命令
sbin/nginx – t – c conf/nginx2.conf
---------------------------------------------------------------------------------------------
当一台服务器中启用多个实例的nginx时(即开启不同端口的nginx),那么启动nginx的时候就要根据各自的nginx配置文件进行启动了,比如:
/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf
/data/nginx1.9/sbin/nginx -c /data/nginx1.9/conf/nginx.conf
/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
通过信号对 Nginx 进行控制
Nginx 支持下表中的信号:
有两种方式来通过这些信号去控制Nginx:
第一是通过logs目录下的nginx.pid查看当前运行的Nginx的进程ID,通过 kill – XXX <pid> 来控制 Nginx,其中 XXX 就是上表中列出的信号名。
如果系统中只有一个Nginx进程,那也可以通过 killall 命令来完成,例如运行 killall – s HUP nginx 来让 Nginx 重新加载配置。
配置 Nginx
先来看一个实际的配置文件:
user nobody;# 工作进程的属主 worker_processes 4;# 工作进程数,一般与 CPU 核数等同 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { use epoll;#Linux 下性能最好的 event 模式 worker_connections 2048;# 每个工作进程允许最大的同时连接数 } 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 off; access_log logs/access.log;# 日志文件名 sendfile on; #tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; include gzip.conf; # 集群中的所有后台服务器的配置信息 upstream tomcats { server 192.168.0.11:8080 weight=10; server 192.168.0.11:8081 weight=10; server 192.168.0.12:8080 weight=10; server 192.168.0.12:8081 weight=10; server 192.168.0.13:8080 weight=10; server 192.168.0.13:8081 weight=10; } server { listen 80;#HTTP 的端口 server_name localhost; charset utf-8; #access_log logs/host.access.log main; location ~ ^/NginxStatus/ { stub_status on; #Nginx 状态监控配置 access_log off; } location ~ ^/(WEB-INF)/ { deny all; } location ~ .(htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js| zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ { root /opt/webapp; expires 24h; } location / { proxy_pass http://tomcats;# 反向代理 include proxy.conf; } error_page 404 /html/404.html; # redirect server error pages to the static page /50x.html # error_page 502 503 /html/502.html; error_page 500 504 /50x.html; location = /50x.html { root html; } } }
Nginx 监控
上面是一个实际网站的配置实例,其中#号后面的文字为配置说明。
上述配置中,首先我们定义了一个 location ~ ^/NginxStatus/,这样通过 http://localhost/NginxStatus/ 就可以监控到 Nginx 的运行信息,显示的内容如下:
Active connections: 70
server accepts handled requests
14553819 14553819 19239266
Reading: 0 Writing: 3 Waiting: 67
NginxStatus 显示的内容意思如下:
active connections – 当前 Nginx 正处理的活动连接数。
server accepts handled requests -- 总共处理了 14553819 个连接 , 成功创建 14553819 次握手 ( 证明中间没有失败的 ), 总共处理了 19239266 个请求 ( 平均每次握手处理了 1.3 个数据请求 )。
reading -- nginx 读取到客户端的 Header 信息数。
writing -- nginx 返回给客户端的 Header 信息数。
waiting -- 开启 keep-alive 的情况下,这个值等于 active - (reading + writing),意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接。
静态文件处理
通过正则表达式,我们可让 Nginx 识别出各种静态文件,例如 images 路径下的所有请求可以写为:
location ~ ^/images/ {
root /opt/webapp/images;
}
而下面的配置则定义了几种文件类型的请求处理方式。
location ~ .(htm|html|gif|jpg|jpeg|png|bmp|ico|css|js|txt)$ {
root /opt/webapp;
expires 24h;
}
对于例如图片、静态 HTML 文件、js 脚本文件和 css 样式文件等,我们希望 Nginx 直接处理并返回给浏览器,这样可以大大的加快网页浏览时的速度。因此对于这类文件我们需要通过 root 指令来指定文件的存放路径,同时因为这类文件并不常修改,通过 expires 指令来控制其在浏览器的缓存,以减少不必要的请求。 expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用)。您可以使用例如以下的格式来书写 Expires:
expires 1 January, 1970, 00:00:01 GMT;
expires 60s;
expires 30m;
expires 24h;
expires 1d;
expires max;
expires off;
动态页面请求处理
Nginx 本身并不支持现在流行的 JSP、ASP、PHP、PERL 等动态页面,但是它可以通过反向代理将请求发送到后端的服务器,例如 Tomcat、Apache、IIS 等来完成动态页面的请求处理。前面的配置示例中,我们首先定义了由 Nginx 直接处理的一些静态文件请求后,其他所有的请求通过 proxy_pass 指令传送给后端的服务器(在上述例子中是 Tomcat)。最简单的 proxy_pass 用法如下:
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
}
这里我们没有使用到集群,而是将请求直接送到运行在 8080 端口的 Tomcat 服务上来完成类似 JSP 和 Servlet 的请求处理。
当页面的访问量非常大的时候,往往需要多个应用服务器来共同承担动态页面的执行操作,这时我们就需要使用集群的架构。 Nginx 通过 upstream 指令来定义一个服务器的集群,最前面那个完整的例子中我们定义了一个名为 tomcats 的集群,这个集群中包括了三台服务器共 6 个 Tomcat 服务。而 proxy_pass 指令的写法变成了:
location / {
proxy_pass http://tomcats;
proxy_set_header X-Real-IP $remote_addr;
}
在 Nginx 的集群配置中,Nginx 使用最简单的平均分配规则给集群中的每个节点分配请求。一旦某个节点失效时,或者重新起效时,Nginx 都会非常及时的处理状态的变化,以保证不会影响到用户的访问。
Nginx的location语法规则:location [=|~|~*|^~] /uri/ { … }
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~和!~* 分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到。
多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):
首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
示例说明:
有如下匹配规则:
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ .(gif|jpg|png|js|css)$ {
#规则D
}
location ~* .png$ {
#规则E
}
location !~ .xhtml$ {
#规则F
}
location !~* .xhtml$ {
#规则G
}
location / {
#规则H
}
产生的效果如下:
访问根目录/, 比如http://localhost/ 将匹配规则A
访问http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问http://localhost/static/a.html 将匹配规则C
访问http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而 http://localhost/static/c.png 则优先匹配到 规则C
访问http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。
访问http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
访问http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。
所以实际使用中,至少有三个匹配规则定义,如下:
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
这里是直接转发给后端应用服务器了,也可以是一个静态首页
第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* .(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
第三个规则就是通用规则,用来转发动态请求到后端应用服务器
非静态文件请求就默认是动态请求,自己根据实际把握
毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}
尽管Nginx整个程序包只有500多K,但麻雀虽小、五脏俱全。 Nginx官方提供的各种功能模块应有尽有,结合这些模块可以完整各种各样的配置要求,例如:压缩、防盗链、集群、FastCGI、流媒体服务器、Memcached 支持、URL 重写等等,更关键的是Nginx拥有Apache和其他HTTP服务器无法比拟的高性能。甚至可以在不改变原有网站的架构上,通过在前端引入Nginx做负载均衡来提升网站的访问速度。
-------------------------------------------------------下面对Nginx的一些特殊设置做一说明-------------------------------------------------------
nginx的全局变量
--------------------------------------------------------------------------------
remote_addr 客户端ip,如:192.168.4.2
binary_remote_addr 客户端ip(二进制)
remote_port 客户端port,如:50472
remote_user 已经经过Auth Basic Module验证的用户名
host 请求主机头字段,否则为服务器名称,如:dwz.stamhe.com
request 用户请求信息,如:GET /?_a=index&_m=show&count=10 HTTP/1.1
request_filename 当前请求的文件的路径名,由root或alias和URI request组合而成,如:/webserver/htdocs/dwz/index.php
status 请求的响应状态码,如:200
body_bytes_sent 响应时送出的body字节数数量。即使连接中断,这个数据也是精确的,如:40
content_length 请求头中的Content-length字段
content_type 请求头中的Content-Type字段
http_referer 引用地址
http_user_agent 客户端agent信息,如:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11
args 如:_a=index&_m=show&count=10
document_uri 与$uri相同,如:/index.php
document_root 针对当前请求的根路径设置值,如:/webserver/htdocs/dwz
hostname 如:centos53.localdomain
http_cookie 客户端cookie信息
cookie_COOKIE cookie COOKIE变量的值
is_args 如果有$args参数,这个变量等于”?”,否则等于”",空值,如?
limit_rate 这个变量可以限制连接速率,0表示不限速
query_string 与$args相同,如:_a=index&_m=show&count=10
realpath_root 如:/webserver/htdocs/dwz
request_body 记录POST过来的数据信息
request_body_file 客户端请求主体信息的临时文件名
request_method 客户端请求的动作,通常为GET或POST,如:GET
request_uri 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。如:/index.php?_a=index&_m=show&count=10
scheme HTTP方法(如http,https),如:http
uri 如:/index.php
request_completion 如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty),如:OK
server_protocol 请求使用的协议,通常是HTTP/1.0或HTTP/1.1,如:HTTP/1.1
server_addr 服务器地址,在完成一次系统调用后可以确定这个值,如:192.168.4.129
server_name 服务器名称,如:dwz.stamhe.com
server_port 请求到达服务器的端口号,如:80
比如访问https://www.wangshibo.com/HouseGroup/index.html,跳转到https://www.wangshibo.com/index.php?r=houseGroup/index rewrite ^/(.*)/index.html https://www.wangshibo.com/index.php?r=$1/index; if ($request_uri ~* "/(jkhwpc|jkhw|jkhwadmin).php") { rewrite ^/(.*)$ http://www.jikehaiwai.com/$1 last; } if ($request_uri ~* "/(qjspc|qjsmob|qjsadmin).php") { rewrite ^/(.*)$ http://www.qianjins.com/$1 last; } -----------可以参考下面nginx的rewrite伪静态设置--------- rewrite ^(.*)/equip(d+).html$ $1/index.php?m=content&c=index&a=lists&catid=$2 last; # nginx rewrite rule rewrite ^(.*)/archiver/((fid|tid)-[w-]+.html)$ $1/archiver/index.php?$2 last; rewrite ^(.*)/forum-([0-9]+)-([0-9]+).html$ $1/forumdisplay.php?fid=$2&page=$3 last; rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+).html$ $1/viewthread.php?tid=$2&extra=page%3D$4&page=$3 last; rewrite ^(.*)/profile-(username|uid)-(.+).html$ $1/viewpro.php?$2=$3 last; rewrite ^(.*)/space-(username|uid)-(.+).html$ $1/space.php?$2=$3 last; rewrite ^(.*)/tag-(.+).html$ $1/tag.php?name=$2 last; rewrite ^/(.*).(asp|aspx|asa|asax|dll|jsp|cgi|fcgi|pl)(.*)$ /404.php last; rewrite ^/(.*)/(admin|cache|editor|file|include|lang|module|skin|template)/(.*).php(.*)$ /404.php last; rewrite ^/(.*)-htm-(.*)$ /$1.php?$2 last; rewrite ^/(.*)/show-([0-9]+)([-])?([0-9]+)?.html$ /$1/show.php?itemid=$2&page=$4 last; rewrite ^/(.*)/list-([0-9]+)([-])?([0-9]+)?.html$ /$1/list.php?catid=$2&page=$4 last; rewrite ^/(.*)/show/([0-9]+)/([0-9]+)?([/])?$ /$1/show.php?itemid=$2&page=$3 last; rewrite ^/(.*)/list/([0-9]+)/([0-9]+)?([/])?$ /$1/list.php?catid=$2&page=$3 last; rewrite ^/(.*)/([A-za-z0-9_-]+)-c([0-9]+)-([0-9]+).html$ /$1/list.php?catid=$3&page=$4 last; rewrite ^/(.*)/([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+).html$ /$1/index.php?moduleid=$2&catid=$3&itemid=$4&page=$5 last; rewrite ^(.*)/([a-z]+)/(.*).shtml$ $1/$2/index.php?rewrite=$3 last; rewrite ^/(com)/([a-z0-9_-]+)/([a-z]+)/(.*).html$ /index.php?homepage=$2&file=$3&rewrite=$4 last; rewrite ^/(com)/([a-z0-9_-]+)/([a-z]+)([/])?$ /index.php?homepage=$2&file=$3 last; rewrite ^/(com)/([a-z0-9_-]+)([/])?$ /index.php?homepage=$2 last;
--------------------------------------------------------------------------------
1.rewrite跳转规则,有以下四种flag标记:
last 基本上都用这个Flag,表示rewrite。
break 中止Rewirte,不在继续匹配。就是说本条规则匹配完成后,终止匹配,不再匹配后面的规则。
redirect 返回临时重定向的HTTP状态302;浏览器地址会显示跳转后的URL地址。
permanent 返回永久重定向的HTTP状态301;浏览器地址会显示跳转后的URL地址。
1)下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
先来看几个小例子说明
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串: location /download/ { rewrite ^(/download/.*)/m/(.*)..*$ $1/nginx-rewrite/$2.gz break; } ----------------------------------------------------------------------------------- 例如当用户输入 www.a.com.cn 自动跳转到www.a.com 这个域名: rewrite ^/(.*)$ http://www.a.com/$1 permanent; ----------------------------------------------------------------------------------- 例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下: if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /nginx-ie/$1 break; } ----------------------------------------------------------------------------------- 例如当用户访问testxqsjapi.xqshijie.com域名时跳转到本机的9501端口 upstream lb-9501 { server 127.0.0.1:9501; } server { listen 80; server_name testxqsjapi.xqshijie.com; root /var/www/vhosts/testxqsjapi.xqshijie.com/; location / { proxy_pass http://lb-9501; } } ---------------------------------------------------------------------------------- 例如下面一例:nginx rewrite 实现二级域名跳转 当访问http://abc.wangshibo.com跳转到http://www.wangshibo.com/wangshibo/abc/ 方法一:这种方法浏览器地址会变www.wangshibo.com/wangshibo/abc server { listen 80; server_name www.wangshibo.com; location / { root /data/wangshibo; index index.html; } } server { listen 80; server_name *.wangshibo.com; if ( $http_host ~* "^(.*).wangshibo.com$") { set $domain $1; rewrite ^(.*) http://www.wangshibo.com/wangshibo/$domain/ break; } } 方法二:当访问http://abc.wangshibo.com/*跳转到http://www.wangshibo.com/wangshibo/abc/* server { listen 80; server_name *.wangshibo.com; root /usr/local/www; #这是里可以加多个目录,如果不加目录,会无法访问到abc.wangshibo.com/目录下的文件,如图片目录/images location ~ ^/(wangshibo|images|styles)/ { proxy_redirect off; proxy_set_header Host www.wangshibo.com; proxy_pass http://192.168.1.2:8080; } location / { set $domain default; if ( $http_host ~* "^(.*).wangshibo.com$") { set $domain $1; } rewrite ^/(.*) /wangshibo/$domain/$1 last; } access_log off; }
再接着看下面的实例说明
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 #这里是直接转发给后端应用服务器了,也可以是一个静态首页 # 第一个必选规则 location = / { proxy_pass http://tomcat:8080/index } # 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项 # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/; } location ~* .(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } #第三个规则就是通用规则,用来转发动态请求到后端应用服务器 #非静态文件请求就默认是动态请求,自己根据实际把握 #毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了 location / { proxy_pass http://tomcat:8080/ }
2)实例说明
1)访问A站跳转(重定向)到B站
server {
listen 80;
server_name www.wangshibo.com ;
rewrite ^(.*) http://www.huanqiu.com$1 permanent;
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
================================================================================
访问一个主域名,自动添加www前缀。比如访问http://kevin.com自动跳转http://www.kevin.com
1) 首先要保证不加www和加www的域名都要解析出来。 在DNS里添加kevin.com和www.kevin.com的解析,比如解析到111.110.11.18 @ IN A 111.110.11.18 www IN A 111.110.11.18 解释: A记录解析kevin.com到111.110.11.18地址上,前面加@或者留空(留空默认就是@) A记录解析www.kevin.com到111.110.11.18地址上,前面加www 2)nginx配置不加www自动跳转到www的域名访问(80或443都一样),有下面两种方法实现: 方法一: 在conf/vhost/kevin.conf文件中配置: server { listen 80; server_name www.kevin.com kevin.com; index index.jsp index.html index.php index.htm; root /var/www/html; access_log /data/nginx/logs/www.kevin.com-access.log main; error_log /data/nginx/logs/www.kevin.com-error.log; if ($host = "kevin.com") { rewrite ^/(.*)$ http://www.kevin.com permanent; } } 方法二(官方推荐这一种nginx的301跳转方法) 在conf/vhost/kevin.conf文件中配置: server { listen 80; server_name kevin.com; return 301 http://www.kevin.com$request_uri; } server { listen 80; server_name www.kevin.com; index index.jsp index.html index.php index.htm; root /var/www/html; access_log /data/nginx/logs/www.kevin.com-access.log main; error_log /data/nginx/logs/www.kevin.com-error.log; }
2)多域名绑定一个目录,并且全部301跳转到其中一个域名(注意:多域名都要解析到本机ip上)
server {
listen 80;
server_name www.wangshibo.com web01.wangshibo.com hehe.wangshibo.com wangshibo.com;
if ($host != 'www.wangshibo.com') {
rewrite ^/(.*)$ http://www.wangshibo.com/$1 permanent;
}
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
上面说明访问http://web01.wangshibo.com、http://hehe.wangshibo.com、http://wangshibo.com的时候都会自动跳转到
http://www.wangshibo.com,并且浏览器地址会显示跳转后的URL地址。
如果是上面多域名访问后都重定向跳转到http://hehe.wangshibo.com,则配置修改如下:
server {
listen 80;
server_name www.wangshibo.com web01.wangshibo.com hehe.wangshibo.com wangshibo.com;
if ($host != 'hehe.wangshibo.com') {
rewrite ^/(.*)$ http://hehe.wangshibo.com/$1 permanent;
}
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
如下配置:多域名中的某个域名访问时发生跳转,其他域名访问时不跳转
server {
listen 80;
server_name www.wangshibo.com web01.wangshibo.com hehe.wangshibo.com wangshibo.com;
if ($host = 'hehe.wangshibo.com') {
rewrite ^/(.*)$ http://www.huanqiu.com/$1 permanent;
}
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
3)将多级目录下的文件转成一个文件,增强seo效果
比如将/wang-123-456-789.html指向wang/123/456/wangshow_789.html
[root@test-huanqiu ~]# cat /usr/local/nginx/conf/vhosts/test.conf
server {
listen 80;
server_name www.wangshibo.com;
rewrite ^/wang-([0-9]+)-([0-9]+)-([0-9]+).html$ http://www.wangshibo.com/wang/$1/$2/wangshow_$3.html last;
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
这样访问http://www.wangshibo.com/wang-123-456-789.html就会跳转到http://www.wangshibo.com/wang/123/456/wangshow_789.html
4)访问的目标文件和目录资源不存在的时候重定向跳转
如下配置,当访问http://www.wangshibo.com/后面的访问资源(文件或目录)不存在时,统统跳转到http://www.wangshibo.com/sorry.html页面
server {
listen 80;
server_name www.wangshibo.com;
if (!-e $request_filename) {
rewrite ^/ http://www.wangshibo.com/sorry.html ;
}
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
5)将站点根目录下某个目录指向二级目录
例如将/huanqiupc/指向/ops/huanqiu/,配置如下:
server {
listen 80;
server_name www.wangshibo.com;
rewrite ^/([0-9a-z]+)pc/(.*)$ http://www.wangshibo.com/ops/$1/$2 last;
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
这样,访问http://www.wangshibo.com/huanqiupc的时候就会跳转到http://www.wangshibo.com/ops/huanqiu/
注意:上面的配置中的last修改为permanent或redirect都可以
以上的配置也适用于:(前提是这些目录要真是存在于站点目录/var/www/html/中,并且权限要正确)
将/wangshibopc/指向/ops/wangshibo/
将/guohuihuipc/指向/ops/guohuihui/
将/hahapc/指向/ops/haha/
......
6)其他的rewrite跳转规则的例子:
server { listen 80; server_name www.wangshibo.com; root /var/www/html; index index.html index.htm; rewrite ^/site/resource/(.*)$ https://www.wangshibo.com/resource/$1 last; rewrite ^/active/Ymf.html$ https://www.wangshibo.com/project/detail.html?project_id=1 last; rewrite ^/active/Ysyg.html$ https://www.wangshibo.com/project/detail.html?project_id=7 last; if ($host ~* "^wangshibo.com$") { rewrite ^/(.*)$ https://www.wangshibo.com/ permanent; } location / { rewrite /abc http://www.huanqiu.com break; #本机站点目录下并不需要真实存在abc这个目录,对虚拟目录的访问都重写到http://www.huanqiu.com } #即访问http://www.wangshibo.com/abc,跳转到http://www.huanqiu.com location /text { rewrite / http://china.huanqiu.com break; #本机站点目录下需要真实存在text目录,对其的访问都重写到http://china.huanqiu.com } #即访问http://www.wangshibo.com/text,跳转到http://china.huanqiu.com }
下面一例:访问http://www.wangshibo.com/g/4HG45SkZ 实际访问地址跳转为 http://110.10.88.99:8081/qun/share/view?code=4HG45SkZ
upstream g_server {
keepalive 64;
server 110.10.88.99:8081 max_fails=2 fail_timeout=5 weight=100;
}
server {
listen 80;
server_name www.wangshibo.com;
rewrite ^/bcloud.(swf|html|js)(.*)$ http://hehe.wangshibo.com/bcloud.$1$2 last;
root /home/web/www;
location ~ .apk$ {
max_ranges 0;
}
location ^~ /g {
proxy_redirect off;
proxy_set_header Host $host;
# proxy_set_header Host $host:$remote_port;
# proxy_set_header REMOTE_PORT $remote_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 1G;
client_body_buffer_size 256k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 600;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_temp_file_write_size 64k;
proxy_pass http://g_server;
#rewrite "/g/(.*$)" www.wangshibo.com/qun/share/view?code=$1 break;
rewrite "/g/(.*$)" /qun/share/view?code=$1 break;
}
}
另外注意:
$1表示第一个变量,即前面rewrite后第一个()内设置的变量
$2表示第二个变量,即前面rewrite后第二个()内设置的变量
再看一例:
访问http://www.wangshibo.com/thumb/transcode 实际访问地址为 http://120.170.190.99:28080/transcode/thumb/transcode
upstream thumb {
keepalive 64;
server 120.170.190.99:28080 max_fails=2 fail_timeout=5 weight=100;
}
server {
listen 80;
server_name www.wangshibo.com ;
root /home/web/www;
location ^~ /thumb {
proxy_pass http://thumb;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
client_max_body_size 1G;
client_body_buffer_size 256k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 60;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_temp_file_write_size 64k;
rewrite "^/(.*)$" /transcode/$1 break;
}
}
----------------------------再看一个访问nginx跳转后的url不变的例子--------------------------------------
需要特别注意的是: proxy_pass 反向代理,可以实现只改变跳转后的内容,而跳转后的原url保持不变! rewrite 重写跳转后会进行重定向,很难实现跳转后的原url不变的需求。 看看之前踩过的坑; 要求访问http://wx2.xqshijie.com/apiwx2/xqsj.php?r=houseGroup%2FgetToken,内容跳转到http://m.xqshijie.com/xqsj.php?r=houseGroup%2FgetToken,但是跳转后的url保持不变! 这是根据path路径进行反向代理的配置,即要求访问http://wx2.xqshijie.com/apiwx2/$1 跳转到http://m.xqshijie.com/$1,跳转后的url不变! 配置如下: [root@fangfull_web1 vhosts]# cat wx2.xqshijie.com.conf server { listen 80; server_name wx2.xqshijie.com; root /Data/app/xqsj_wx2/dist; index index.html; #if ($http_x_forwarded_for !~ ^(124.65.197.154|103.10.86.28|103.10.86.8)) { # rewrite ^.*$ /maintence.php last; #} location /apiwx2/ { proxy_pass https://m.xqshijie.com/; } access_log /var/log/betawx2.log main; location / { try_files $uri $uri/ @router; index index.html; } #rewrite ^(.+)$ /index.html last; location @router { rewrite ^.*$ /index.html last; } } 根据上面配置后,就可以实现访问http://wx2.xqshijie.com/apiwx2/xqsj.php?r=houseGroup%2FgetToken,实际显示的是https://m.xqshijie.com/xqsj.php?r=houseGroup%2FgetToken的内容,但是跳转后的原来的url不变! 如果采用rewrite重写规则,即将: location /apiwx2/ { proxy_pass https://m.xqshijie.com/; } 改为 location /apiwx2/ { rewrite ^/apiwx2(.*)$ https://m.xqshijie.com.$1 last; } 那么,访问http://wx2.xqshijie.com/apiwx2/xqsj.php?r=houseGroup%2FgetToken,实际显示的是https://m.xqshijie.com/xqsj.php?r=houseGroup%2FgetToken的内容,但是跳转后的url已经变了! 上面碰到过的坑: 由于访问http://m.xqshijie.com就会自动跳转到https://m.xqshijie.com,所以如果将上面的配置改为(即将https://m.xqshijie.com改为http://m.xqshijie.com): location /apiwx2/ { proxy_pass http://m.xqshijie.com/; } 这样,访问http://wx2.xqshijie.com/apiwx2/xqsj.php?r=houseGroup%2FgetToken,实际显示的是https://m.xqshijie.com/xqsj.php?r=houseGroup%2FgetToken的内容,但是跳转后的原来的url已经变了! 原因是因为这里经过了两次跳转,即rewrite->http->https,所以跳转后的url变了。 解决办法:就是直接rewrite跳转到https,即proxy_pass https://m.xqshijie.com/;
----------------------------下面的跳转规则表示---------------------------------------
访问http://www.wangshibo.com/wangshibo/ops就会跳转到http://www.wangshibo.com/ops/wangshibo
访问http://www.wangshibo.com/wangshibo/beijing就会跳转到http://www.wangshibo.com/beijing/wangshibo
......
即由"wangshibo/变量"-->"变量/wangshibo"
server {
listen 80;
server_name www.wangshibo.com;
rewrite ^/wangshibo/(.*)$ http://www.wangshibo.com/$1/wangshibo last;
root /var/www/html;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
访问http://www.wangshibo.com/ops/web 跳转到 http://www.wangshibo.com/web/ops/web/
server { listen 80; server_name www.wangshibo.com; rewrite ^/ops/(.*)$ http://www.wangshibo.com/$1/ops/$1 break; root /var/www/html; index index.html index.php index.htm; access_log /usr/local/nginx/logs/image.log; }
访问http://www.wangshibo.com/wang/123 实际访问地址跳转为 http://www.hehe.com/qun/share/view?code=123
server { listen 80; server_name www.wangshibo.com; rewrite ^/wang/(.*)$ http://www.hehe.com/qun/share/view?code=$1 last; root /var/www/html; index index.html index.php index.htm; access_log /usr/local/nginx/logs/image.log; }
其他配置实例
如果nginx在用户使用IE浏览器访问情况下,则重定向到/nginx-ie目录下 配置如下: if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /nginx-ie/$1 break; } 多目录转成参数 abc.domian.com/sort/2 => abc.domian.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; } 目录自动加"/",前提是访问目录存在 配置如下: if (-d $request_filename){ rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; } 三级域名跳转 配置如下: if ($http_host ~* “^(.*).i.beijing.com$”) { rewrite ^(.*) http://www.wangshibo.com$1/; break; } 针对站点根目录下的某个子目录作镜向 配置如下:就会把http://www.huanqiu.com的内容(即首页)镜像到/var/www/html下的ops目录下了 server { listen 80; server_name www.wangshibo.com; root /var/www/html; location ^~ /ops { rewrite ^.+ http://www.huanqiu.com/ last; break; } index index.html index.php index.htm; access_log /usr/local/nginx/logs/image.log; } 域名镜像(其实就是域名跳转) server { listen 80; server_name www.wangshibo.com; root /var/www/html; rewrite ^/(.*) http://www.huanqiu.com/$1 last; index index.html index.php index.htm; access_log /usr/local/nginx/logs/image.log; } 其他: rewrite ^/(space|network)-(.+).html$ /$1.php?rewrite=$2 last; rewrite ^/(space|network).html$ /$1.php last; rewrite ^/([0-9]+)$ /space.php?uid=$1 last; rewrite ^(.*)/archiver/((fid|tid)-[w-]+.html)$ $1/archiver/index.php?$2 last; rewrite ^(.*)/forum-([0-9]+)-([0-9]+).html$ $1/forumdisplay.php?fid=$2&page=$3 last; rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+).html$ $1/viewthread.php?tid=$2&extra=page%3D$4&page=$3 last; rewrite ^(.*)/profile-(username|uid)-(.+).html$ $1/viewpro.php?$2=$3 last; rewrite ^(.*)/space-(username|uid)-(.+).html$ $1/space.php?$2=$3 last; rewrite ^(.*)/tag-(.+).html$ $1/tag.php?name=$2 last;
目录对换:/1234/xxx ----->xxx?id=1234
配置如下:
[root@test-huanqiu ~]# vim /usr/local/nginx/conf/vhosts/test.conf
server {
listen 80;
server_name www.wangshibo.com;
root /var/www/html;
rewrite ^/(d+)/(.+)/ /$2?id=$1 last;
index index.html index.php index.htm;
access_log /usr/local/nginx/logs/image.log;
}
[root@test-huanqiu ~]# cat /var/www/html/ops/index.html
nginx的目录对换的跳转测试
如上配置后,那么:
访问http://www.wangshibo.com/?id=567567567567567 的结果就是http://www.wangshibo.com/的结果
访问http://www.wangshibo.com/ops/?id=wangshibo 的结果就是http://www.wangshibo.com/ops的结果
访问http://www.wangshibo.com/wang/?id=123111 的结果就是http://www.wangshibo.com/wang的结果
.......
2.反向代理(proxy_pass)
简单测试nginx反向代理和负载均衡功能的操作记录(1)-----http代理
简单测试nginx反向代理和负载均衡功能的操作记录(2)-----https代理
3.缓存设置
nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录
nginx缓存配置的操作记录梳理
4.防盗链。关于Nginx防盗链具体设置,可参考:Nginx中防盗链(下载防盗链和图片防盗链)的操作记录
location ~* .(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
下面设置文件反盗链并设置过期时间:
location ~*^.+.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
valid_referers none blocked *.wangshibo.com*.wangshibo.net localhost 218.197.67.14;
if ($invalid_referer) {
rewrite ^/ http://img.wangshibo.net/leech.gif;
return 412;
break;
}
access_log off;
root /opt/lampp/htdocs/web;
expires 3d;
break;
}
这里的return 412 是自定义的http状态码,默认为403,方便找出正确的盗链的请求
“rewrite ^/ http://img.wangshibo.net/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力
“expires 3d”所有文件3天的浏览器缓存
5.根据文件类型设置过期时间
1)expires起到控制页面缓存的作用,合理的配置expires可以减少很多服务器的请求;
2)对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的。
3)Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
要配置expires,可以在http段中或者server段中或者location段中加入;
如下:控制图片等过期时间为30天,如果图片文件不怎么更新,过期可以设大一点;如果频繁更新,则可以设置得小一点,具体视情况而定
location ~ .(gif|jpg|jpeg|png|bmp|swf|ico)$ {
root /var/www/img/;
expires 30d;
}
location ~ .*.(js|css)$ {
expires 10d;
}
location ~* .(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}
location ~ .(wma|wmv|asf|mp3|mmf|zip|rar|swf|flv)$ {
root /var/www/upload/;
expires max;
}
expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用)
语法:expires [time|epoch|max|off]
默认值:off
expires指令控制HTTP应答中的“Expires”和“Cache-Control”Header头部信息,启动控制页面缓存的作用
time:可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。
time值还控制"Cache-Control"的值:
负数表示no-cache
正数或零表示max-age=time
epoch:指定“Expires”的值为 1 January,1970,00:00:01 GMT
max:指定“Expires”的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年。(即设置过期时间最最长)
-1:指定“Expires”的值为当前服务器时间-1s,即永远过期。
off:不修改“Expires”和"Cache-Control"的值
expires使用了特定的时间,并且要求服务器和客户端的是中严格同步。
而Cache-Control是用max-age指令指定组件被缓存多久。
对于不支持http1.1的浏览器,还是需要expires来控制。所以最好能指定两个响应头。但HTTP规范规定max-age指令将重写expires头。
如何检测nginx中设置的expires网页过期时间是否生效?
方法:
打开webkaka的网站速度诊断工具(http://pagespeed.webkaka.com/),输入你的网页地址,检测后,立即可以看到设置是否生效了。如下图所示:
上图可以看到,被检测网页的js文件过期时间为1天(12h)。
6.禁止访问某个文件或目录
1)禁止访问以txt或doc结尾的文件
location ~* .(txt|doc)${
root /da