开发的应用采用F5负载均衡交换机,F5将请求转发给5台hp unix服务器,每台服务器有多个webserver实例,对外提供web服务和socket等接口服务。之初,曾有个小小的疑问为何不采用开源的 apache、Nginx软件负载,F5设备动辄几十万,价格昂贵?自己一个比较幼稚的问题,后续明白:F5是操作于IOS网络模型的传输 层,Nginx、apache是基于http反向代理方式,位于ISO模型的第七层应用层。直白些就是TCP UDP 和http协议的区别,Nginx不能为基于TCP协议的应用提供负载均衡。
了解了二者之间的区别于应用场景,对Nginx产生浓厚的兴趣,阅读张宴的<实战Nginx>(这个85年的小伙子年轻有为羡慕+妒忌),搞 明白了大致原理和配置,Ubuntu10.10,window下对Nginx+tomcat负载均衡做了配置尝试,将全部请求转发到tomcat,并未做 静态,动态分开,图片防盗链等配置。
Nginx 介绍
Nginx (发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。 其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、 腾讯,另外知名的微网志Plurk也使用nginx。
上面的全是Nginx介绍基本上是废话,下面转入正题,图文结合展示基本配置,首先是window环境、其次是Ubuntu环境(Vbox虚拟)。本文主要基于Nginx下配置两台tomcat,结构如下图:
Window xp环境:Nginx+Tomcat6
1、下载地址
http://nginx.org/en/download.html ,这里我们推荐下载稳定版(stable versions),本文采用nginx-0.8.20。
2、目录结构
Nginx-
|_ conf 配置目录
|_ contrib
|_ docs 文档目录
|_ logs 日志目录
|_ temp 临时文件目录
|_ html 静态页面目录
|_ nginx.exe 主程序
window下安装Nginx极其简单,解压缩到一个无空格的英文目录即可(个人习惯,担心中文出问题),双击nginx启动,这里我安装到:D:\server目录,下面涉及到的tomcat也安装在此目录。
DOS环境启动
若果想停止nginx,dos环境运行命令:nginx -s stop
3、nginx.conf配置
Nginx配置文件默认在conf目录,主要配置文件为nginx.conf,我们安装在D:\server\nginx-0.8.20、默认主配置文件 为D:\server\nginx-0.8.20\nginx.conf。下面是nginx作为前端反向代理服务器的配置。
Nginx.conf代码
1. #Nginx所用用户和组,window下不指定
2. #user niumd niumd;
3.
4. #工作的子进程数量(通常等于CPU数量或者2 倍于CPU)
5. worker_processes 2 ;
6.
7. #错误日志存放路径
8. #error_log logs/error.log;
9. #error_log logs/error.log notice;
10. error_log logs/error.log info;
11.
12. #指定pid存放文件
13. pid logs/nginx.pid;
14.
15. events {
16. #使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
17. #use epoll;
18.
19. #允许最大连接数
20. worker_connections 2048 ;
21. }
22.
23. http {
24. include mime.types;
25. default_type application/octet-stream;
26.
27. #定义日志格式
28. #log_format main '$remote_addr - $remote_user [$time_local] $request '
29. # '"$status" $body_bytes_sent "$http_referer" '
30. # '"$http_user_agent" "$http_x_forwarded_for"' ;
31.
32. #access_log off;
33. access_log logs/access.log;
34.
35. client_header_timeout 3m;
36. client_body_timeout 3m;
37. send_timeout 3m;
38.
39. client_header_buffer_size 1k;
40. large_client_header_buffers 4 4k;
41.
42. sendfile on;
43. tcp_nopush on;
44. tcp_nodelay on;
45.
46. #keepalive_timeout 75 20 ;
47.
48. include gzip.conf;
49. upstream localhost {
50. #根据ip计算将请求分配各那个后端tomcat,许多人误认为可以解决session问题,其实并不能。
51. #同一机器在多网情况下,路由切换,ip可能不同
52. #ip_hash;
53. server localhost:18081 ;
54. server localhost:18080 ;
55. }
56.
57. server {
58. listen 80 ;
59. server_name localhost;
60.
61. location / {
62. proxy_connect_timeout 3 ;
63. proxy_send_timeout 30 ;
64. proxy_read_timeout 30 ;
65. proxy_pass http://localhost;
66. }
67.
68. }
69. }
代理设置如下:
Proxy.conf代码
1. proxy_redirect off;
2. proxy_set_header Host $host;
3. proxy_set_header X-Real-IP $remote_addr;
4. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
5. client_max_body_size 10m;
6. client_body_buffer_size 128k;
7. proxy_connect_timeout 300 ;
8. proxy_send_timeout 300 ;
9. proxy_read_timeout 300 ;
10. proxy_buffer_size 4k;
11. proxy_buffers 4 32k;
12. proxy_busy_buffers_size 64k;
13. proxy_temp_file_write_size 64k;
gzip压缩相关配置如下:
Gzip.conf代码
1. gzip on;
2. gzip_min_length 1000 ;
3. gzip_types text/plain text/css application/x-javascript;
4、Tomcat配置
对于tomcat大家都很熟悉,只需要修改server.xml配置文件即可,这里我们以apache-tomcat-6.0.14为例,分别在 server目录,解压缩并命名为:apache-tomcat-6.0.14_1、apache-tomcat-6.0.14_2。
第一处端口修改:
Xml代码
1.
2. < Server port = "18006" shutdown = "SHUTDOWN" >
第二处端口修改:
Xml代码
1.
2. < Connector port = "18081" protocol = "HTTP/1.1"
3. connectionTimeout = "20000"
4. redirectPort = "8443" />
5.
6.
第三处端口修改:
Java代码
1. "8009" protocol= "AJP/1.3" redirectPort= "8443" />
Engine元素增加jvmRoute属性:
Xml代码
1. < Engine name = "Catalina" defaultHost = "localhost" jvmRoute = "tomcat1" >
两个tomcat的端口别重复,保证能启动起来,另一个tomcat配置希捷省略,监听端口为18080,附件中我们将上传所有的配置信息。
5、验证配置与测试负载均衡
首先测试nginx配置是否正确,测试命令:nginx -t (默认验证:conf\nginx.conf),也可以指定配置文件路径。
此例nginx安装目录:D:\server\nginx-0.8.20,dos环境下图画面成功示例:
其次验证tomcat,启动两个tomcat,不出现端口冲突即为成功(tomcat依赖的java等搞“挨踢”的就废话不说了);
最后验证配置负载均衡设置,http://localhost/ 或http://localhost/index.jsp 。我修改了index.jsp页面,增加日志输出信息,便于观察。注意:左上角小猫头上的:access tomcat2、access tomcat1。说明访问了不同的tomcat。
至此window下nginx+tomcat负载均衡配置结束,关于tomcat Session的问题通常是采用memcached,或者采用nginx_upstream_jvm_route ,他是一个 Nginx 的扩展模块,用来实现基于 Cookie 的 Session Sticky 的功能。如果tomcat过多不建议session同步,server间相互同步session很耗资源,高并发环境容易引起Session风暴。请根据 自己应用情况合理采纳session解决方案。
Ubuntu10.10环境:Nginx+Tomcat6
我们下面简单说下ubuntu10.10下如何安装配置,主要以图片为主,简单解释。
1、下载Nginx
地址:http://nginx.org/en/download.html ,linux版本:nginx-0.8.20.tar.。解压缩命令:
tar -zxvf nginx-0.8.20.tar.gz
2、编译安装Nginx
Nginx依赖一些其他PCRE、openssl(依赖libssl-dev),本人笔记本Ubuntu环境已经安装PCRE,仅需安装依赖的openssl,下面我们简单说下如何安装PCRE和openssl等
PCRE下载地址:ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
Shell代码
1. tar zxvf pcre- 8.01 .tar.gz
2. cd pcre-8.01
3. sudo ./configure
4. sodu make
5. sodu make install
openssl通过apt-get install安装,命令、截图如下:
Shell代码
1. sudo apt-get install openssl
2. sudo apt-get install libssl-dev
3. //如缺少其他包,请采用此方法安装,ubuntu有依赖提示
依赖的软件包安装完毕,下面来编译Nginx:
Shell代码
1. #将window共享目录软件拷贝到当前工作目录
2. cp /mnt/fileshare/nginx-0.8 . 20 .tar.gz ./
3.
4. #解压缩软件包
5. tar zxvf nginx-0.8 . 20 .tar.gz
6.
7. cd nginx-0.8 . 20
8. //编译源码,默认使用nobody,指定本机已存在的用户,组,启用nginx-status功能,监控nginx状态。启动debug
9. sudo ./configure --user=niumd --group=niumd --with-debug --with-http_stub_status_module
10.
11.
12. sudo make
13. sudo make install
编译安装正确结束,按照上述window下方法检查默认配置,然后在默认配置下启动nginx,访问http://127.0.0.1 ,如下图说明成功
Nginx配置成功后我们对window下nginx.conf少做修改,如下:
Ubuntu nginx.conf代码
1. #Nginx所用用户和组
2. user niumd niumd;
3.
4. #工作的子进程数量(通常等于CPU数量或者2 倍于CPU)
5. worker_processes 2 ;
6.
7. #错误日志存放路径
8. #error_log logs/error.log;
9. #error_log logs/error.log notice;
10. error_log logs/error.log info;
11.
12. #指定pid存放文件
13. pid logs/nginx.pid;
14.
15. events {
16. #使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue
17. use epoll;
18.
19. #允许最大连接数
20. worker_connections 2048 ;
21. }
22.
23. http {
24. include mime.types;
25. default_type application/octet-stream;
26.
27. #定义日志格式
28. #log_format main '$remote_addr - $remote_user [$time_local] $request '
29. # '"$status" $body_bytes_sent "$http_referer" '
30. # '"$http_user_agent" "$http_x_forwarded_for"' ;
31.
32. #access_log off;
33. access_log logs/access.log;
34.
35. client_header_timeout 3m;
36. client_body_timeout 3m;
37. send_timeout 3m;
38.
39. client_header_buffer_size 1k;
40. large_client_header_buffers 4 4k;
41.
42. sendfile on;
43. tcp_nopush on;
44. tcp_nodelay on;
45.
46. #keepalive_timeout 75 20 ;
47.
48. include gzip.conf;
49. upstream localhost {
50. #ip_hash
51. #ip_hash;
52. server localhost:18081 ;
53. server localhost:18080 ;
54. }
55.
56. server {
57. listen 80 ;
58. server_name localhost;
59.
60. location / {
61. proxy_connect_timeout 3 ;
62. proxy_send_timeout 30 ;
63. proxy_read_timeout 30 ;
64. proxy_pass http://localhost;
65. }
66.
67. }
68. }
对于上面关于ubuntu下Nginx配置和window下基本相同,区别在使用的IO网络模型,linux下建议使用epoll,另外就是运行所用的用户和组;
3、配置tomcat
请参考window下配置,完全相同。
4、启动停止nginx
ubuntu下启动nginx与window稍有不同,大致启动停止方法如下。
Java代码
1. #nginx目录执行
2. sbin/nginx
3. 或通过-c 指定配置文件
4. sbin/nginx -c usr/local/nginx8.20 /conf/nginx/conf
Shell代码
1. niumd@niumd-laptop:/usr/local/nginx$ pwd
2. /usr/local/nginx
3. niumd@niumd-laptop:/usr/local/nginx$ sudo sbin/nginx -t
4. the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
5. configuration file /usr/local/nginx/conf/nginx.conf test is successful
6. niumd@niumd-laptop:/usr/local/nginx$ sudo sbin/nginx -v
7. nginx version: nginx/0.8 . 20
8. niumd@niumd-laptop:/usr/local/nginx$ sudo sbin/nginx -V
9. nginx version: nginx/0.8 . 20
10. built by gcc 4.4 . 3 (Ubuntu 4.4 . 3 -4ubuntu5)
11. configure arguments: --user=niumd --group=niumd --with-debug --with-http_sub_module
12. niumd@niumd-laptop:/usr/local/nginx$ sudo sbin/nginx
13. niumd@niumd-laptop:/usr/local/nginx$ ps -ef|grep nginx
14. root 5158 1 0 22 : 32 ? 00 : 00 : 00 nginx: master process sbin/nginx
15. niumd 5159 5158 0 22 : 32 ? 00 : 00 : 00 nginx: worker process
16. niumd 5161 1577 0 22 : 32 pts/ 0 00 : 00 : 00 grep --color=auto nginx
17. niumd@niumd-laptop:/usr/local/nginx$
我们通过ps -ef|grep nginx,看到如下结果:
注意:在启动时linux提示一句警告【warn】……,是因为我们设置的 #允许最大连接数 worker_connections 2048,超过linux默认1024的限制。
停止:kill -信号类型 pid
nginx/logs目录下有个nginx。pid的文件,此文件记录了每次运行的pid,也可以通过ps命令查询。
信号类型如下:
信号类型 | 描述 |
RERM.INT | 快速关闭 |
HUP | 平滑重启,加载配置 |
USR1 | 重新加载日志 |
USER2 | 平滑升级执行程序 |
WINCH | 从容关闭工作进程 |
QUIT | 从容关闭 |
在实际配置中,有的地方用last并不能工作,换成break就可以,其中的原理是对于根目录的理解有所区别,按我的测试结果大致是这样的。
#location / {
#proxy_pass http://test;
#alias /home/html/;
#root /home/html;
#rewrite "^/a/(.*)/.html$" /1.html last;
#}
在#location / { 配置里:
1、使用root指定源:使用last和break都可以
2、使用proxy_pass指定源:使用last和break都可以
3、使用alias指定源:必须使用last
在location /a/或使用正则的location ~ ^/a/里:
1、使用root指定源:使用last和break都可以
2、使用proxy_pass指定源:使用break和last结果有所区别
3、使用alias指定源:必须使用last
其中区别主要在proxy_pass这个标签上,再看看几个测试结果:
location / {
root /home/html;
}
location /a/ {
proxy_pass http://test;
rewrite "^/a/(.*)/.html$" /1.html last;
}
在这段配置里,使用last访问是可以访问到东西的,不过,它出来的结果是:/home/html/1.html;可我需要的是http://test/1.html?使用break就可以了。
location / {
root /home/html;
}
location /a/ {
proxy_pass http://test;
rewrite "^/a/(.*)/.html$" /a/1.html last;
}
在这段配置里,返回错误,因为last会重新发起请求匹配,所以造成了一个死循环,使用break就可以访问到http://test/a/1.html。
所以,使用last会对server标签重新发起请求,而break就直接使用当前的location中的数据源来访问,要视情况加以使用。一般在非根的location中配置rewrite,都是用的break;而根的location使用last比较好,因为如果配置了fastcgi或代理访问jsp文件的话,在根location下用break是访问不到。测试到rewrite有问题的时候,也不妨把这两者换换试试。
至于使用alias时为什么必须用last,估计是nginx本身就限定了的,怎么尝试break都不能成功。
nginx重写(rewrite)相关
~*.jsp$ 以什么。jsp结尾的不区分大小写;
^/$ /shop/market/list.html?st=1 last;以什么开始。。。
rewrite ^/(.*)$ /index.php/$1 last;
对url后面/以外的内从进行临时从定向,last的状态码是301
例如你访问www.baidu.com/abc.html他最后会跳转到www.baidu.com/index.php/abc.html 这使用的是正则表达式,
http://www.cnblogs.com/cgli/archive/2011/05/16/2047920.html
rewrite只是会改写路径部分的东东,不会改动用户的输入参数,因此这里的if规则里面,你无需关心用户在浏览器里输入的参数,rewrite后会自动添加的,因此,我们只是加上了一个?号和后面我们想要的一个小小的参数 ***https=1就可以了。
nginx的rewrite规则参考:
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹pei
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
last 相当于Apache里的[L]标记,表示完成rewrite,呵呵这应该是最常用的
break 终止匹配, 不再匹配后面的规则
redirect 返回302临时重定向 地址栏会显示跳转后的地址
permanent 返回301永久重定向 地址栏会显示跳转后的地址
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri
http://blog.csdn.net/aigoleague/article/details/7842154
nginx有以下内置变量
$args, 请求中的参数;
$content_length, HTTP请求信息里的"Content-Length";
$content_type, 请求信息里的"Content-Type";
$document_root, 针对当前请求的根路径设置值;
$document_uri, 与$uri相同;
$host, 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate, 对连接速率的限制;
$request_method, 请求的方法,比如"GET"、"POST"等;
$remote_addr, 客户端地址;
$remote_port, 客户端端口号;
$remote_user, 客户端用户名,认证用;
$request_filename, 当前请求的文件路径名
$request_body_file
$request_uri, 请求的URI,带查询字符串;
$query_string, 与$args相同;
$scheme, 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
$server_protocol, 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr, 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name, 请求到达的服务器名;
$server_port, 请求到达的服务器端口号;
$uri, 请求的URI,可能和最初的值有不同,比如经过重定向之类的。
这些变量可以用在rewrite规则里,也可以打印日志的时候用
nginx 日志
nginx 日志相关指令主要有两条,一条是log_format,用来设置日志格式,另外一条是access_log,用来指定日志文件的存放路径、格式和缓存大 小,通俗的理解就是先用log_format来决定把哪些信息打印到日志里,然后在用zccess_log定义虚拟主机时或全局日志时 在把定义的log_format 跟在后面;
log_format 格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_s ent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
main表示给后面定义的日志个数取了个名为main的名称,便于在access_log指令中引用
上面的log_format打印出来的日志形如
111.22.33.44 - - [10/Jan/2001:02:14:14 +0200] "GET / HTTP/1.1" 200 1234 "http://www.fromserver.com/from.htm" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
对比日志格式和输出的结果可以发现,日志格式用一对单引号包起来,多个日志格式段用可以放在不同的行,最后用分号(;)结尾
单引号中的双引号("),空白符,中括号([)等字符原样输出,比较长的字符串通常用双引号(")包起来,看起来不容易更加清楚,$开始的变量会替换为真实的值
$remote_user 为-表示没有值
access_log 指令示例
access_log /home/example/nginx/logs/access.log main;
/home/example/nginx/logs/access.log表示nginx日志将输出到该文件,每条日志内容如main定义
多目录转成参数
abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2
if ($host ~* (.*)\.domain\.com) {
# ~*不区分大小写匹配,
# '.' 匹配任意单个字符
#()表示将()里面的匹配结果保存到变量中,第一个括号中匹配的放在$1变量,第二个括号中匹配的值放在$2中,依此类推
#开始一个新的匹配,会把$1等变量的值替换为新的匹配的值,这里$1的值为abc
#为了保存匹配结果,可以像下面的行那样,将匹配的结果放在一个新的变量中
set $sub_name $1;
#这里开始一次新的匹配,$1的值变成了新的值2
#每一次rewrite的第一个参数对应的是host后面的字符串,这里表示/sort/2
#这个也有待验证,还有就是如果第二次只有两个括号,第一次有三个,则 $3的值是多少?
#rewrite 第一个参数最后的\/? 表示最后可以带/也可以不带/
rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&name=$sub_name&id=$1 last;
}
待验证问题:
if ($host ~* (.*)\.domain\.co)
是说 不区分大小写的情况下,$host中是否包含(.*)\.domain\.co模式,因此$host=abc.domain.com也算匹配模式
要排除.com需要在模式后加$符号,即修改为if ($host ~* (.*)\.domain\.co$)
目录对换
/123456/xxxx -> /xxxx?id=123456
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
我自己写的是这样的
rewrite ^/\/(\d+)\/(\w+)\/? /$2?id=$1 last;
‘.’匹配任意单个字符,.+则匹配至少包含一个字符的任意字符串,给出的结果其实是将第一级目录放到之后目录的后面
/123456/abc/def/ rewrite后结果为/abc/def?id=123456
注意:/123456/abc/def/最后一个/都被去掉了
例如下面设定nginx在用户使用ie浏览器访问的时候,重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
# ~ 区分大小写匹配
rewrite ^(.*)$ /nginx-ie/$1 break;
}
下面是 $http_user_agent取值的一个例子
"$http_user_agent" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)"
上面的例子是用Mozilla浏览器访问,但是仍然包含MSIE子串,因此,上面的rewrite规则应该是不严格的,应该用if ($http_user_agent ~ ^MSIE),限定以 MSIE开头更加严格
目录自动加“/”
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
用([^/])匹配最后一个非'/'的字符,然后自己强行再添加一个'/'($2变量后的那个)
Location 指令
是用来为匹配的 URI 进行配置,URI 即语法中的"/uri/",可以是字符串或正则表达式。但如果要使用正则表达式,则必须指定前缀。
我的理解是:如果URI中包含某个模式,则进行后面的处理。
基本语法
location [ =|~|~*|^~|@ ] /uri/ { … }
〖=〗 表示精确匹配,如果找到,立即停止搜索并立即处理此请求。
〖~ 〗 表示区分大小写匹配
〖~*〗 表示不区分大小写匹配
〖^~ 〗 表示只匹配字符串,不查询正则表达式。
〖@〗 指定一个命名的location,一般只用于内部重定向请求。
匹配过程
首先对字符串进行匹配查询,最确切的匹配将被使用。然后,正则表达式的匹配查询开始,匹配第一个结果后会停止搜索,如果没有找到正则表达式,将使用字符串的搜索结果,如果字符串和正则都匹配,那么正则优先级较高。
配置实例
location = / {
# 只匹配对 / 目录的查询.
[ config A ]
}
location / {
# 匹配以 / 开始的查询,即所有查询都匹配。
[ config B ]
}
location ^~ /images/ {
# 匹配以 /images/ 开始的查询,不再检查正则表达式。
[ config C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配以gif, jpg, or jpeg结尾的文件,但优先级低于config C。
[ config D ]
}
禁止ht access
location ~/\.ht {
#ht是一个文件或目录,无论ht在哪一级,都禁止访问)
deny all;
}
禁止多个目录
location ~ ^/(cron|templates)/ {
#禁止访问第一级目录中名为cron或templates的目录
deny all;
break;
}
禁止以/data开头的文件
可以禁止/data目录下所有文件的访问;
location ~ ^/data {
deny all;
}
禁止单个文件
location ~ /data/sql/data.sql {
deny all;
}
expires
语法: expires [time|epoch|max|off]
默认值: expires off
作用域: http, server, location
该指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标,(起到控制页面缓存的作用)。可以在time值中使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定的 time 值来获得。
epoch 指定“Expires”的值为 1 January, 1970, 00:00:01 GMT。
max 指定“Expires”的值为 31 December 2037 23:59:59 GMT,“Cache-Control”的值为10年。
-1 指定“Expires”的值为 服务器当前时间 -1s,即永远过期
“Cache-Control”头标的值由指定的时间来决定:
负数:Cache-Control: no-cache
正数或零:Cache-Control: max-age = #, # 为指定时间的秒数s。其他的单位有d(天),h(小时)
"off" 表示不修改“Expires”和“Cache-Control”的值
控制图片等过期时间为30天,这个时间可以设置的更长。具体视情况而定
location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {
log_not_found off; #不记录404 not found 错误日志
expires 30d;
break;
}
控制匹配/resource/或者/mediatorModule/里所有的文件缓存设置到最长时间
location ~ /(resource|mediatorModule)/ {
root /opt/demo;
expires max;
}
设定某个文件的过期时间;这里为600秒,并不记录访问日志
location ^~ /html/scripts/loadhead_1.js {
access_log off;
root /opt/lampp/htdocs/web;
expires 600;
break;
}
文件反盗链并设置过期时间
这里的return 412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求
“rewrite ^/ http://leech.divmy.com/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力
“expires 3d”所有文件3天的浏览器缓存
location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194;
if ($invalid_referer) {
rewrite ^/ http://leech.divmy.com/leech.gif;
return 412;
break;
}
access_log off;
root /opt/lampp/htdocs/web;
expires 3d;
break;
}
设置GZIP
一般情况下压缩后的html、css、js、php、jhtml等文件,大小能降至原来的25%,也就是说,原本一个100k的html,压缩后只剩下25k。这无疑能节省很多带宽,也能降低服务器的负载。
在nginx中配置gzip比较简单
具体可见http://wiki.codemongers.com/NginxChsHttpGzipModule
一般情况下只要在nginx.conf的http段中加入下面几行配置即可
gzip on;
gzip_min_length 1000;
gzip_buffers 4 8k;
gzip_types text/plain application/x-javascript text/css text/html application/xml;
可以通过网页gzip检测工具来检测网页是否启用了gzip
只充许固定ip访问网站,并加上密码
root /opt/htdocs/www;
allow 208.97.167.194;
allow 222.33.1.2;
allow 231.152.49.4;
deny all;
auth_basic “C1G_ADMIN”;
auth_basic_user_file htpasswd;
将多级目录下的文件转成一个文件,增强seo效果
/job-123-456-789.html 指向/job/123/456/789.html
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
将根目录下某个文件夹指向2级目录
如/shanghaijob/ 指向 /area/shanghai/
如果你将last改成permanent,那么浏览器地址栏显是/location/shanghai/
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
上面例子有个问题是访问/shanghai 时将不会匹配
rewrite ^/([0-9a-z]+)job$ /area/$1/ last;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
这样/shanghai 也可以访问了,但页面中的相对链接无法使用,
如./list_1.html真实地址是/area/shanghia/list_1.html会变成/list_1.html,导至无法访问。
那我加上自动跳转也是不行咯
(-d $request_filename)它有个条件是必需为真实目录,而我的rewrite不是的,所以没有效果
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
知道原因后就好办了,让我手动跳转吧
rewrite ^/([0-9a-z]+)job$ /$1job/ permanent;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}
域名跳转
server
{
listen 80;
server_name jump.88dgw.com;
index index.html index.htm index.php;
root /opt/lampp/htdocs/www;
rewrite ^/ http://www.88dgw.com/;
access_log off;
}
多域名转向
server_name www.7oom.com/ www.divmy.com/;
index index.html index.htm index.php;
root /opt/lampp/htdocs;
if ($host ~ “c1gstudio\.net”) {
rewrite ^(.*) http://www.7oom.com$1/ permanent;
}
三级域名跳转
if ($http_host ~* “^(.*)\.i\.c1gstudio\.com$”) {
rewrite ^(.*) http://top.88dgw.com$1/;
break;
}
域名镜向
server
{
listen 80;
server_name mirror.c1gstudio.com;
index index.html index.htm index.php;
root /opt/lampp/htdocs/www;
rewrite ^/(.*) http://www.divmy.com/$1 last;
access_log off;
}
某个子目录作镜向
location ^~ /zhaopinhui {
rewrite ^.+ http://zph.divmy.com/ last;
break;
}
discuz ucenter home (uchome) rewrite
rewrite ^/(space|network)-(.+)\.html$ /$1.php?rewrite=$2 last;
rewrite ^/(space|network)\.html$ /$1.php last;
rewrite ^/([0-9]+)$ /space.php?uid=$1 last;
discuz 7 rewrite
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;
给discuz某版块单独配置域名
server_name bbs.c1gstudio.com news.c1gstudio.com;
location = / {
if ($http_host ~ news\.divmy.com$) {
rewrite ^.+ http://news.divmy.com/forum-831-1.html last;
break;
}
}
discuz ucenter 头像 rewrite 优化
location ^~ /ucenter {
location ~ .*\.php?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location /ucenter/data/avatar {
log_not_found off;
access_log off;
location ~ /(.*)_big\.jpg$ {
error_page 404 /ucenter/images/noavatar_big.gif;
}
location ~ /(.*)_middle\.jpg$ {
error_page 404 /ucenter/images/noavatar_middle.gif;
}
location ~ /(.*)_small\.jpg$ {
error_page 404 /ucenter/images/noavatar_small.gif;
}
expires 300;
break;
}
}
jspace rewrite
location ~ .*\.php?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location ~* ^/index.php/
{
rewrite ^/index.php/(.*) /index.php?$1 break;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
Nginx与Apache的Rewrite规则实例对比
简单的Nginx和Apache 重写规则区别不大,基本上能够完全兼容。例如:
Apache Rewrite 规则:
RewriteRule ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 [L]
RewriteRule ^/ceshi/$ /zl/ceshi.php [L]
RewriteRule ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 [L]
RewriteRule ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 [L]
Nginx Rewrite 规则:
rewrite ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 last;
rewrite ^/ceshi/$ /zl/ceshi.php last;
rewrite ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 last;
rewrite ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 last;
由以上示例可以看出,Apache的Rewrite规则改为Nginx的Rewrite规则,其实很简单:Apache的RewriteRule指令换成Nginx的rewrite指令,Apache的[L]标记换成Nginx的last标记,中间的内容不变。
如果Apache的Rewrite规则改为Nginx的Rewrite规则后,使用nginx -t命令检查发现nginx.conf配置文件有语法错误,那么可以尝试给条件加上引号。例如一下的Nginx Rewrite规则会报语法错误:
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 规则:
rewrite ^/html/tagindex/([a-zA-Z]+)/.*$ http://$host/$1/ permanent;
以上示例中,我们注意到,Nginx Rewrite 规则的置换串中增加了“http://$host”,这是在Nginx中要求的。
另外,Apache与Nginx的Rewrite规则在变量名称方面也有区别,例如:
Apache Rewrite 规则:
RewriteRule ^/user/login/$ /user/login.php?login=1&forward=http://%{HTTP_HOST} [L]
Nginx Rewrite 规则:
rewrite ^/user/login/$ /user/login.php?login=1&forward=http://$host last;
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标记;
允许指定的域名访问本站,其他域名一律跳转到http://www.aaa.com
Apache Rewrite 规则:
RewriteCond %{HTTP_HOST} ^(.*?)\.domain\.com$
RewriteCond %{HTTP_HOST} !^qita\.domain\.com$
RewriteCond %{DOCUMENT_ROOT}/market/%1/index.htm -f
RewriteRule ^/wu/$ /market/%1/index.htm [L]
Nginx的if指令不支持嵌套,也不支持AND、OR等多条件匹配,相比于Apache的RewriteCond,显得麻烦一些,但是,我们可以通过下一页的Nginx配置写法来实现这个示例:
Nginx Rewrite 规则:
if ($host ~* ^(.*?)\.domain\.com$) set $var_wupin_city $1;
set $var_wupin ‘1′;
if ($host ~* ^qita\.domain\.com$)
set $var_wupin ‘0′;
if (!-f $document_root/market/$var_wupin_city/index.htm)
set $var_wupin ‘0′;
if ($var_wupin ~ ‘1′)
rewrite ^/wu/$ /market/$var_wupin_city/index.htm last;
}
ps配置事例:
user root;
worker_processes 8;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 8024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
keepalive_timeout 60;
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;
upstream banksteel_sso_webapp {
server 192.168.200.57:8888;
}
upstream banksteel_user_webapp {
server 192.168.200.57:8983;
}
upstream banksteel_user_mgtapp {
server 192.168.200.57:8984;
}
upstream banksteel_mgtweb{
server 192.168.100.118:8081;
}
upstream banksteel_membercenter{
server 192.168.100.215:8082;
}
upstream banksteel_www{
server 192.168.100.215:8083;
}
upstream banksteel_api{
server 192.168.100.203:8091;
}
upstream banksteel_integral_shop_webapp {
server 192.168.200.57:8801;
}
upstream banksteel_integral_shop_mgtapp {
server 192.168.200.57:9801;
}
upstream banksteel_base_mgtapp {
server 192.168.200.64:8801;
}
upstream banksteel_trade_mgtapp {
server 192.168.200.64:8802;
}
upstream banksteel_trade_webapp {
server 192.168.200.64:8803;
}
upstream banksteel_cart_webapp {
server 192.168.200.64:8804;
}
upstream banksteel_shop_webapp {
server 192.168.200.64:7001;
}
upstream banksteel_shop_mgtapp{
server 192.168.200.64:7011;
}
server {
listen 80;
server_name sso.banksteel.com;
location / {
proxy_pass http://banksteel_sso_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server{
listen 80;
server_name poptest.banksteel.com;
location /{
proxy_pass http://banksteel_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server {
listen 80;
server_name membertest.banksteel.com;
location /
{
proxy_pass http://banksteel_user_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /head
{
proxy_pass http://banksteel_user_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /indexcas.jsp
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /order
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /resource
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /member/auction
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /shop
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /consult2
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /seller
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /norights
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /skin
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /skin-member
{
proxy_pass http://banksteel_user_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral_shop
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /game
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral_skin
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /attentionShop
{
proxy_pass http://banksteel_membercenter;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /cart
{
proxy_pass http://banksteel_trade_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /skin-cart
{
proxy_pass http://banksteel_trade_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server{
listen 80;
server_name chaoshitest.banksteel.com;
location /{
rewrite ^/$ /shop/market/list.html?st=1 last;
proxy_pass http://banksteel_www;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server{
listen 80;
server_name restest.banksteel.com;
location /{
rewrite ^/search$ /resource/list.html?st=2&showAll=1 last;
proxy_pass http://banksteel_www;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server{
listen 80;
server_name caigoutest.banksteel.com;
location /{
rewrite ^/$ /consult/buyoffer/list.html?st=4 last;
proxy_pass http://banksteel_www;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server{
listen 80;
server_name wwwtest.banksteel.com;
location / {
proxy_pass http://banksteel_www;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /api {
proxy_pass http://banksteel_api;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral_shop
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /game
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral_game
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral_skin
{
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server {
listen 80;
server_name integral.banksteel.com;
location / {
proxy_pass http://banksteel_integral_shop_webapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server
{
listen 80;
server_name mgttest.banksteel.com;
location ~*.jsp$
{
proxy_pass http://banksteel_mgtweb;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /assets
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /bill
{
proxy_pass http://banksteel_mgtweb;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /member
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /integral
{
proxy_pass http://banksteel_integral_shop_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location ^~/skin-integral
{
proxy_pass http://banksteel_integral_shop_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /skin-member
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /skin-trade
{
proxy_pass http://banksteel_trade_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /resource
{
proxy_pass http://banksteel_trade_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /resourcefile
{
proxy_pass http://banksteel_mgtweb;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /trade
{
proxy_pass http://banksteel_trade_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /noauth.htm
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /select
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /main.htm
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /index.htm
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /logout.htm
{
proxy_pass http://banksteel_user_mgtapp;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
location /
{
proxy_pass http://banksteel_mgtweb;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
}
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}