说到前头:经过一番测试,把域名解析到nginx 上了,网站访问量比较大,nginx,按照下面的方法,我本以为会很快,结果网站基本还是打不开。
我觉得问题可能出在:
1、nginx 所在服务器和 源服务器不是一个机房,不在同一个局域网中
2、对linux 了解比较少,不知道哪里配置错误了
经过不懈努力 反复实验,终于搞定了 nginx 缓存动态页面的方法,和设置缓存过期的方法
需求:
公司服务器用的是 windows + IIS + asp.net + ms sql
网站访问量比较大,如果直接用动态网站上去,基本打不开
1、最早的时候网站使用的是 在服务器上写程序,生成html ,让用户直接访问html,虽然效果很好,但是程序难以维护
每次生成要 很久很久,有时候 生成 html 的页面会死掉,会断开链接,服务器上面消耗的内存cpu 也比较大
2、再后来我自己写了一个程序,把网站所有请求都 发送给该程序,该程序 去请求动态页面内容,缓存到 本地,然后第二个用户再去访问的时候,去判断 缓存文件是否过期(我设置30分钟过期),如果没过期就直接输出该文件
程序在这里:http://www.oschina.net/code/snippet_172400_10925
3、我把代码贴出去之后,故意夸大其词说大型网站静态化方案,果然马上有人来呛我,说了一些我不知道 或者了解比较少的东西,nginx 和 proxy cache 然后就google baidu 疯狂的找资料,之前接触 linux 也比较少,刚好微软查版权,导致公司大部分服务器换为 linux,图片服务器也要换成linux,我借助此机会 去接触 linux,并配置了 图片服务器,用 nginx 反向代理把 源图片服务器上的图片缓存到 nginx 下,果然很方便
方案在这里:http://my.oschina.net/foxidea/blog/90787
4、图片服务器配置完成之后,就一直想 用nginx 去缓存我们的动态网站页面,但是有几个问题:
动态网站和图片服务器不一样,动态网站要每过几个小时重新生成一次缓存,有ajax 交互等是实时的
而图片服务器 只要缓存下来就不用再去管了,图片也不会变化
所以又经过一番波折 ,最后还是高成功了:
这里用虚拟机配置了下:
nginx 配置文件内容:
主要是这一句:
proxy_cache_path /www/ levels=1:2 keys_zone=Z:10m inactive=1m max_size=30g;
这一句定义一个区域,名字是 Z ,在内存中的空间为10MB ,硬盘中的最大空间为 30G;
inactive=1m 是,1分钟之后缓存失效 ,从新从源服务器请求
这里纠正一下,inactive=1m 如果缓存1分钟没人访问,nginx 会删除掉这些缓存
/usr/local/nginx/conf/nginx.conf
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } 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 logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; proxy_cache_path /www/ levels=1:2 keys_zone=Z:10m inactive=1m max_size=30g; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root /www/; #expires max; #proxy_store on; #proxy_store_access user:rw group:rw all:rw; #proxy_temp_path /www/; proxy_cache Z; proxy_cache_valid 200 1m; #expires max; include proxy.conf; if ( !-e $request_filename) { proxy_pass http://192.168.1.199:45815; } } #这里设置当 访问 /ajax/目录下的内容时候,直接从源服务器读取,主要用于ajax 的访问请求,要求实时的 location /ajax/ { include proxy.conf; if ( !-e $request_filename) { proxy_pass http://192.168.1.199:45815; } } #location ~.*\.(jpg|png|jpeg|gif) #{ # expires max; #} #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443; # server_name localhost; # ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_timeout 5m; # ssl_protocols SSLv2 SSLv3 TLSv1; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
/usr/local/nginx/conf/proxy.conf
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; proxy_set_header Accept-Encoding 'gzip'; client_max_body_size 100m; client_body_buffer_size 256k; proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 512k; proxy_buffers 8 512k; proxy_busy_buffers_size 512k; proxy_temp_file_write_size 512k;
一开始我就这样配置,认为可以成功了,结果发现动态文件无法被缓存,而html 文件可以被缓存,后来就到很多地方去问,
心想会不会是因为 文件 的 头信息或者Last-Modified 信息和 ETag 造成的,就去问,http://www.dewen.org/q/9769/nginx+%E5%A6%82%E4%BD%95%E7%BC%93%E5%AD%98%E5%8A%A8%E6%80%81%E9%A1%B5%E9%9D%A2%EF%BC%9F
发现果真如此,马上修改源服务器的动态文件,加入以下代码:
<%@ Page Language="C#" %> <% string date = Request.Headers.Get("If-Modified-Since"); if (date != null) { Response.StatusCode = 304; Response.StatusDescription = "from cache"; return; } DateTime expDate = new DateTime(2037, 12, 31, 23, 55, 55); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetExpires(expDate); Response.Cache.SetMaxAge(expDate - DateTime.Now); Response.Cache.SetLastModified(new DateTime(2000, 1, 1)); %> <%=DateTime.Now.ToString()%>
然后发现就可以缓存动态文件了。至此,下一步我就可以用nginx 作为用户访问的 服务器了
这里截一些图:
源服务器 http://192.168.1.199:45815/ajax/r.aspx
源服务器 http://192.168.1.199:45815/d.aspx
源服务器 http://192.168.1.199:45815/default.html
虚拟机中 nginx 的域名是 localhost
通过虚拟机centos 浏览器 firefox 分别去访问
localhost/d.aspx
localhost/ajax/r.aspx
localhost/default.html
不停刷新(ctrl+f5) 看页面变化
访问:localhost/default.html 刷新始终没有变化,手工去修改 源服务器 http://192.168.1.199:45815/default.html ,发现一分钟之后,会变化
访问:localhost/ajax/r.aspx 刷新始终是变化的,显示当前的时间
访问:localhost/d.aspx 刷新 ,和 localhost/default.html 效果一样,一分钟之后才会变化
#经过测试,上面的方法好像不行,似乎永久缓存了
修改下动态页面的代码:
<%@ Page Language="C#" %> <script runat="server"> void EchoCachePageHeader() { DateTime expDate = DateTime.Now.AddSeconds(60);//设置缓存60秒 Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetExpires(expDate); Response.Cache.SetMaxAge(expDate - DateTime.Now); Response.Cache.SetLastModified(DateTime.Now); } </script> <% //If-Modified-Since: string date = Request.Headers.Get("If-Modified-Since"); Response.Write(date); Response.Write("<br />"); if (date != null) { try { DateTime ifDate = Convert.ToDateTime(date); if ((DateTime.Now - ifDate).TotalSeconds <= 60) { Response.StatusCode = 304; Response.StatusDescription = "from cache"; return; } else { EchoCachePageHeader(); } } catch { EchoCachePageHeader(); } } else { EchoCachePageHeader(); } %> <br /> <%=DateTime.Now %>
装了两个浏览器测试了下缓存,是一样的结果,这样就非常好了