Nginx部署web缓存服务环境 - 操作记录

 

web缓存位于内容源Web服务器和客户端之间,当用户访问一个URL时,Web缓存服务器会去后端Web源服务器取回要输出的内容,然后,当下一个请求到来时,如果访问的是相同的URL,Web缓存服务器直接输出内容给客户端,而不是向源服务器再次发送请求.Web缓存降低了内容源Web服务器,数据库的负载,减少了网络延迟,提高了用户访问的响应速度,增强了用户体验.

web缓存服务器中,最著名的要数Squid Cache(简称为Squid),Squid是一个流浪的自由软件的代理服务器和Web缓存服务器。
===================================================================
Squid可以作为网页服务器的前置cache服务器缓存相关请求来提高Web服务器的速度;
Squid可以为一组人共享网络资源而缓存万维网,域名系统和其他网络搜索;
Squid可以通过过滤流量帮助网络安全,到局域网通过代理上网.
===================================================================
然而,当下多数公司网站的图片,js,css等文件的缓存会选择Nginx的web缓存服务。

如下将对nginx的web缓存功能的整体配置进行梳理性记录:
Nginx的Web缓存服务主要由proxy_cache相关指令集和fastcgi_cache相关指令集构成。
1)proxy_cache相关指令集用于反向代理时,对后端内容源服务器进行缓存.Nginx的proxy_cache缓存功能,十分稳定,速度不逊于Squid!

2)fastcgi相关指令集主要用于对FastCGI的动态程序进行缓存.两者功能基本一样.在功能上,Nginx已经具备Squid所拥有的Web缓存加速功能,清除指定URL缓存功能.而在性能上,Nginx对多核CPU的利用,胜过Squid不少.另外,在反向代理,负载均衡,健康检查,后端服务器故障转移,重写,易用性上,Nginx也比Squid强大很多.这使得一台Nginx可以同时作为"负载均衡服务器"与"Web缓存服务器"来使用.

proxy_cache相关指令集
(1)proxy_cache指令
语法: proxy_cache zone_name ;
该指令用于设置哪个缓存区将被使用,zone_name的值为proxy_cache_path指令创建的缓存区的名称。proxy_pass 指定获取静态内容的地址,其实proxy_cache的原理就是从一个指定的地址获取内容,然后缓存。当下次访问时,nginx会自动判断有没有缓存文件?如果有的话缓存文件是不是已经过期。

(2)proxy_cache_path指令
语法 proxy_cache_path path [levels=number]

keys_zone=zone_name:zone_size[inactive=time] [max_size=size];
该指令用于设置缓存文件的存放路径.

例如:
proxy_cache_path /usr/local/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g ;
解释:
path 表示存放目录
levels 表示指定该缓存空间有两层hash目录,第一层目录为1个字母,第二层目录为2个字母,
保存的文件名会类似/usr/local/nginx/proxy_cache_dir/c/29/XXXXXX ;
keys_zone参数用来为这个缓存区起名.
500m 指内存缓存空间大小为500MB
inactive的1d指如果缓存数据在1天内没有被访问,将被删除。相当于expires过期时间的配置
max_size的30g是指硬盘缓存空间为30G

(3)proxy_cache_methods指令
语法:proxy_cache_methods[GET HEAD POST];
该指令用于设置缓存哪些HTTP方法,默认缓存HTTP GET/HEAD方法,不缓存HTTP POST 方法

(4)proxy_cache_min_uses指令
语法:proxy_cache_min_uses the_number
该指令用于设置缓存的最小使用次数,默认值为1

(5)proxy_cache_valid指令
语法: proxy_cache_valid reply_code [reply_code...] time ;
该指令用于对不同返回状态码的URL设置不同的缓存时间.
例如:
proxy_cache_valid 200 302 10m ;
proxy_cache_valid 404 1m ;
设置200,302状态的URL缓存10分钟,404状态的URL缓存1分钟.

(6)proxy_cache_key指令
语法: proxy_cache_key line ;
该指令用来设置Web缓存的Key值,Nginx根据Key值md5哈希存储缓存.一般根据$host(域名),$request_uri(请求的路径)等变量组合成proxy_cache_key .

proxy_cache缓存配置的完整示例(多数nginx缓存的配置):
1)下载nginx和第三方的ngx_cache_purge模块的编译安装包(官网:http://labs.frickle.com/nginx_ngx_cache_purge/),将ngx_cache_purge编译到到Nginx中,用来清除指定URL的缓存
[root@test-huanqiu ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc            //首先安装依赖
[root@test-huanqiu ~]# cd /usr/local/src
[root@test-huanqiu src]# wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
[root@test-huanqiu src]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@test-huanqiu src]# tar -zxvf ngx_cache_purge-2.3.tar.gz
[root@test-huanqiu src]# tar zxvf nginx-1.8.0.tar.gz
[root@test-huanqiu src]# cd nginx-1.8.0.tar.gz
[root@test-huanqiu nginx-1.8.0]# ./configure --user=www --group=www --add-module=../ngx_cache_purge-2.3 --prefix=/usr/local/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@test-huanqiu src]# make && make install

2)接着,在同一分区下创建两个缓存目录,分别供proxy_temp_path , proxy_cache_path指令设置缓存路径.
注意:proxy_temp_path和proxy_cache_path指定的路径必须在同一磁盘分区,决不能跨区分,因为它们之间是硬链接的关系,避免不通文件系统之间的磁盘IO消耗。
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/proxy_cache_path             #注意,这两个目录的权限一定要是www.www,即是nginx进程权限
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/proxy_temp_path               #这是缓存文件的临时存放目录

3)在配置文件nginx.conf中对扩展名为gif,jpg,jpeg,png,bmp,swf,js,css的图片,flash,javascript , css文件开启Web缓存,其他文件不缓存。

[root@test-huanqiu src]# vim /usr/local/nginx/conf/nginx.conf
user  www;
worker_processes  8;
 
events {
    worker_connections  65535;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;

    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;

#要想开启nginx的缓存功能,需要添加此处的两行内容!
#设置Web缓存区名称为cache_one,内存缓存空间大小为500M,缓存的数据超过1天没有被访问就自动清除;访问的缓存数据,硬盘缓存空间大小为30G
    proxy_cache_path /usr/local/nginx/proxy_cache_path levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g;

#创建缓存的时候可能生成一些临时文件存放的位置 
    proxy_temp_path /usr/local/nginx/proxy_temp_path; 

    fastcgi_connect_timeout 3000;
    fastcgi_send_timeout 3000;
    fastcgi_read_timeout 3000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 8 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
 
    
    client_header_timeout 600s;
    client_body_timeout 600s;
 
    client_max_body_size 100m;              
    client_body_buffer_size 256k;            
 
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
 

    include vhosts/*.conf;
}

[root@test-huanqiu src]# ulimit -n 65535
[root@test-huanqiu src]# mkdir /usr/local/nginx/conf/vhosts

如果执行"nginx -t"检查配置文件的时候,报错:
nginx: [emerg] unknown directive "  proxy_temp_path" in /usr/local/nginx/conf/nginx.conf:21
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

nginx: [emerg] unknown directive "  proxy_cache_path" in /usr/local/nginx/conf/nginx.conf:21
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

可能原因:nginx.conf里关于这两行的配置有误,比如这两行前面的空格有误。可以先删除空格,然后再空格键设置空格,防止不规范空格。

[root@test-huanqiu src]# vim /usr/local/nginx/conf/vhosts/wang.conf

upstream LB-WWW {
      ip_hash;
      server 192.168.1.101:80 max_fails=3 fail_timeout=30s;     #max_fails = 3 为允许失败的次数,默认值为1
      server 192.168.1.102:80 max_fails=3 fail_timeout=30s;     #fail_timeout = 30s 当max_fails次失败后,暂停将请求分发到该后端服务器的时间
      server 192.168.1.118:80 max_fails=3 fail_timeout=30s;
    }
 
 
server {
     listen       80;
     server_name  www.wangshibo.com;
     index index.html index.php index.htm;
     root /var/www/html;

     access_log  /usr/local/nginx/logs/www-access.log main;
     error_log  /usr/local/nginx/logs/www-error.log;

     location / {
         proxy_pass http://LB-WWW;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;             #跟后端服务器连接超时时间,发起握手等候响应时间
         proxy_send_timeout 300;                #后端服务器回传时间,就是在规定时间内后端服务器必须传完所有数据
         proxy_read_timeout 600;                #连接成功后等待后端服务器的响应时间,已经进入后端的排队之中等候处理
         proxy_buffer_size 256k;                #代理请求缓冲区,会保存用户的头信息以供nginx进行处理
         proxy_buffers 4 256k;                  #同上,告诉nginx保存单个用几个buffer最大用多少空间
         proxy_busy_buffers_size 256k;          #如果系统很忙时候可以申请最大的proxy_buffers
         proxy_temp_file_write_size 256k;       #proxy缓存临时文件的大小
         proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
         proxy_max_temp_file_size 128m;
        }

     location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {          
      #使用Web缓存区cache_one,已在nginx.conf的缓存配置中命名的。
      proxy_cache cache_one ;
      #对不同HTTP状态码缓存设置不同的缓存时间
      proxy_cache_valid 200 304 12h ;
      proxy_cache_valid 301 302 1m ;
      proxy_cache_valid any 1m ;
      #设置Web缓存的Key值,Nginx根据Key值md5哈希存储缓存,这里根据"域名,URI,
      #参数"组合成Key
      proxy_cache_key $host$uri$is_args$args;
     }
 
    #用于清除缓存的url设置
    #假设一个URL为http://www.wangshibo.com/test.gif,那么就可以通过访问http://www.wangshibo.com/purge/test.gif清除该URL的缓存。
    location ~ /purge(/.*) {
      #设置只允许指定的IP或IP段才可以清除URL缓存
      allow 127.0.0.1 ;
      allow 192.168.0.0/16 ;
      deny all ;
      proxy_cache_purge cache_one $host$1$is_args$args ;
    }

}

fastcgi_cache相关指令集
(1)fastcgi_cache指令
语法:fastcgi_cache zone_name;
该指令用于设置哪个缓存区将被使用,zone_name的值为fastcgi_cache_path指令创建的缓存区名称.

(2)fastcgi_cache_path指令
语法:fastcgi_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
该指令用于设置缓存文件的存放路径,
例如:
fastcgi_cache_path /usr/local/nginx/fastcgi_cache_dir levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g ;
注意这个指令只能在http标签内配置,
levels指定该缓存空间有两层hash目录,第一层目录为1个字母,第二层为2个字母,保存的
文件名会类似/usr/local/nginx/fastcgi_cache_dir/c/29/XXXX;
keys_zone参数用来为这个缓存区起名,
500m指内存缓存空间大小为500MB;
inactive的1d指如果缓存数据在1天内没有被访问,将被删除;
max_size的30g是指硬盘缓存空间为30GB

(3)fastcgi_cache_methods指令
语法:fastcgi_cache_methods [GET HEAD POST] ;
该指令用于设置缓存哪些HTTP方法,默认缓存HTTP GET/HEAD 方法,不缓存HTTP POST方法

(4)fastcgi_cache_min_uses指令
语法:fastcgi_cache_min_uses the_number;
该指令用于设置缓存的最小使用次数,默认值为1.

(5)fastcgi_cache_valid指令
fastcgi_cache_valid reply_code [reply_code...] time;
该‎指令用于对不同返回状态码的URL设置不同的缓存时间.
fastcgi_cache_valid 200 302 10m ;
fastcgi_cache_valid 404 1m ;
设置200,302状态的URL缓存10分钟,404状态的URL缓存1分钟.
如果不指定状态码,直接指定缓存时间,则只有200,301,302状态的URL缓存5分钟.

(6)fastcgi_cache_key指令
语法:fastcgi_cache_key line ;
该指令用来设置Web缓存的Key值,Nginx根据Key值md5哈希存储缓存.一般根据FastCGI服务器的地址和端口,$request_uri(请求的路径)等变量组合成fastcgi_cache_key。

fastcgi_cache缓存配置的完整示例
1)首先,在同一分区下创建两个缓存目录,分别供fastcgi_temp_path,fastcgi_cache_path指令设置缓存路径.
注意:两个指定设置的缓存路径必须为同一磁盘分区,不能跨分区.
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/fastcgi_temp_path
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/fastcgi_cache_path
2)配置文件nginx.conf对扩展名为gif,jpg,jpeg,png,bmp,swf,js,css的图片,Flash,JavaScript,CSS文件开启Web缓存,其他文件不缓存.

[root@test-huanqiu src]# vim /usr/local/nginx/conf/nginx.conf
........
http{
  #fastcgi_temp_path和fastcgi_cache_path指定的路径必须在同一分区
  fastcgi_temp_path /usr/local/nginx/fastcgi_temp_path ;
  #设置Web缓存区名称为cache_one,内存缓存空间大小为500MB,自动清除超过1天没有被

  #访问的缓存数据,硬盘缓存空间大小为30G
  fastcgi_cache_path /usr/local/nginx/fastcgi_cache_path levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g ;
........
}
[root@test-huanqiu src]# vim /usr/local/nginx/conf/vhosts/wang.conf
  server{
  .......
    
    location ~ .*\.(php|php5)$ {
      #使用Web缓存区cache_one
      fastcgi_cache cache_one ;
      #对不同的HTTP状态码缓存设置不同的缓存时间
      fastcgi_cache_valid 200 10m ;
      fastcgi_cache_valid 301 302 1h ;
      fastcgi_cache_valid an 1m ;
      #设置Web缓存的key值,Nginx根据key值md5哈希存储缓存,这里根据"FastCGI服务  

    #器的IP,端口,请求的URI"组合成Key。
      fastcgi_cache_key 127.0.0.1:9000$requet_uri ;
      #FastCGI服务器
      fastcgi_pass 127.0.0.1:9000 ;
      fastcgi_index index.php ;
      include fcgi.conf ;
    }
}

ngx_cache_purge 是 nginx 的第三方那个模块,用于清除 FastCGI, proxy, SCGI and uWSGI 缓存,nginx默认安装就会带有反向代理的功能,但想要更好的使用,还得配备frickle.com的ngx_cache_purge模块,用于清除指定URL的缓存。
proxy_cache和fastcgi_cache构成了Nginx的缓存,proxy_cache主要用于反向代理时,对后端内容源服务器进行缓存fastcgi_cache主要用于对FastCGI的动态程序进行缓存。两者的功能基本上一样。
-> proxy_cache的作用是缓存后端服务器的内容,可能是任何内容,包括静态的和动态。
-> proxy_cache缓存减少了nginx与后端通信的次数,节省了传输时间和后端宽带。
-> fastcgi_cache的作用是缓存fastcgi生成的内容,很多情况是php生成的动态的内容。
-> fastcgi_cache缓存减少了nginx与php的通信的次数。

                                               在单机上部署nginx的cache缓存服务操作记录                                         

根据业务部门需求,申请一台文件的cache服务器。如下记录在单台机器上部署Nginx缓存服务过程:
nginx缓存配置(缓存配置的参数这里就不做过多解释了,在前面的文档中已说明过,这里只做简单记录)
[root@storage01 ~]# cat /data/nginx/conf/nginx.conf|grep -v "^$"|grep -v "#"
user  www;
worker_processes  8;
  
events {
    worker_connections  65535;
}
  
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
 
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
 
    proxy_temp_path /data/nginx/proxy_temp;
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g;
     
    client_header_timeout 600s;
    client_body_timeout 600s;
  
    client_max_body_size 50m;             
    client_body_buffer_size 256k;           
  
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
  
    include vhosts/*.conf;
}


注意:缓存目录/proxy_cache和/proxy_temp一定要在同一个分区下,并且权限一定要和nginx程序权限一致(即要有写入权限,否则不能生产缓存文件)!
[root@storage01 ~]# mkdir /data/nginx/proxy_cache
[root@storage01 ~]# mkdir /data/nginx/proxy_temp
[root@storage01 ~]# chown -R www.www /data/nginx/proxy_cache
[root@storage01 ~]# chown -R www.www /data/nginx/proxy_temp 
[root@storage01 ~]# chmod -R 777 /data/nginx/proxy_cache
[root@storage01 ~]# chmod -R 777 /data/nginx/proxy_temp 

[root@storage01 ~]# cat /data/nginx/conf/vhosts/8888.conf 
server {
     listen       8888;
     server_name  localhost;

     access_log  /data/nginx/logs/8888-access.log main;
     error_log  /data/nginx/logs/8888-error.log;

location / {
     index index.html index.htm;
     root /data/img/;
    }
}

[root@storage01 ~]# cat /data/nginx/conf/vhosts/img.conf 
upstream cache {
      server localhost:8888 max_fails=3 fail_timeout=30s;
    }

server {
     listen       80;
     server_name  img.wang.com;

     access_log  /data/nginx/logs/img-access.log main;
     error_log  /data/nginx/logs/img-error.log;

     location / {
         proxy_pass http://cache;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;

         proxy_cache cache_one ;
         proxy_cache_valid 200 304 12h ;
         proxy_cache_valid 301 302 1m ;
         proxy_cache_valid any 1m ;
         proxy_cache_key $host$uri$is_args$args;
        }
  
    location ~ /purge(/.*) {
      allow all ;
      proxy_cache_purge cache_one $host$1$is_args$args ;
      error_page 405 =200 /purge$1;
    }
}

访问域名测试

[root@storage01 ~]# ll -d /data/img/
drwxr-xr-x 3 www www 4096 Aug 21 14:56 /data/img/
[root@storage01 ~]# ll /data/img/
total 8
-rwxr-xr-x 1 www www   31 Aug 16 15:44 index.html
drwxr-xr-x 2 www www 4096 Aug 21 14:57 upload
[root@storage01 ~]# cat /data/img/index.html 
缓存服务器!!!!!
[root@storage01 ~]# ll /data/img/upload/
total 140
-rw-r--r-- 1 www www 140935 Aug 17 09:31 test.jpg

查看缓存文件

[root@storage01 ~]# ll /data/nginx/proxy_cache/
total 24
drwx------ 3 www www 4096 Aug 21 16:57 2
drwx------ 3 www www 4096 Aug 21 16:56 3
drwx------ 3 www www 4096 Aug 21 17:05 4
drwx------ 3 www www 4096 Aug 21 16:55 6
drwx------ 3 www www 4096 Aug 21 16:55 7
drwx------ 3 www www 4096 Aug 21 16:57 b
[root@storage01 ~]# ll /data/nginx/proxy_cache/2
total 4
drwx------ 2 www www 4096 Aug 21 16:57 fc
[root@storage01 ~]# ll /data/nginx/proxy_cache/3
total 4
drwx------ 2 www www 4096 Aug 21 17:08 05

上面缓存文件的结构是由levels=1:2决定的,即第一层目录是一个字母命名,第二层目录是两个字母表示

缓存文件强磁盘打满该怎么办?
由于写入路径为一个单一目录,只能写入一块磁盘。一块磁盘很快就会被打满,解决该问题有如下两种方法:
1)将多块磁盘做磁盘阵列? 缺点是:减小了实际的存储空间。
2)巧妙得运用proxy_cache_path的目录结构,由于levels=1:2,这导致缓存文件的目录结构为两层,每层目录名,都是由hash函数生成。
如上,可以将/data/nginx/proxy_cache/下的一级目录通通软链接到大空间的分区下。

如果nginx缓存配置后,proxy_cache_path缓存目录下不能生成缓存文件的原因:

1)/data/nginx/proxy_cache和/data/nginx/proxy_temp的权限问题(如上,这俩目录权限要是www.www,最好777权限)
2)proxy_cache_valid和proxy_pass这两条,就算在单机部署,也要通过proxy_pass代理到自己的对应访问端口下。
proxy_pass指定获取静态内容的地址,其实proxy_cache的原理就是从一个你指定的地址获取内容,然后缓存。当下次你访问时,nginx会自动判断有没有缓存文件?
如果有的话缓存文件是不是已经过期(缓存文件的有效期就是第一条设置的)?如果前面两条任何一条成立就会从proxy_pass的地址重新获取页面信息。

手动清除缓存(用到模块ngx_cache_purge)。通过http://img.wang.com/purge/upload/test.jpg手动清理缓存

再次访问http://img.wang.com/purge/upload/test.jpg进行缓存清理,由于上面已经清理过一次了,所以再次使用这个url进行清理的话,就会报404

需要再次访问http://img.wang.com/upload/test.jpg(如果如上清理缓存后,访问这个失败,就尝试完全清理浏览器缓存),就会再次生成缓存,由此再可以使用上面的purge的url路径进行缓存清理!

[root@storage01 ~]# cd /data/nginx/proxy_cache/
[root@storage01 proxy_cache]# ll
total 8
drwx------ 3 www www 4096 Aug 21 17:23 3
drwx------ 3 www www 4096 Aug 21 17:23 b
[root@storage01 proxy_cache]# rm -rf ./*
[root@storage01 proxy_cache]# ll
total 0
[root@storage01 proxy_cache]# /data/nginx/sbin/nginx -s reload

然后访问http://img.wang.com/upload/test.jpg,强制刷新几次。随后就会发现缓存文件就会自动生成了!
[root@storage01 proxy_cache]# ll
total 8
drwx------ 3 www www 4096 Aug 21 17:26 3
drwx------ 3 www www 4096 Aug 21 17:26 b
[root@storage01 proxy_cache]# ll b
total 4
drwx------ 2 www www 4096 Aug 21 17:26 a1

                                          nginx代理中的缓冲缓存优化说明                                               

Nignx反向代理的一个问题是代理大量用户时会增加服务器进程的性能冲击影响。在大多数情况下,可以很大程度上能通过利用Nginx的缓冲和缓存功能减轻。
当代理到另一台服务器,两个不同的连接速度会影响客户的体验:
-> 从客户机到Nginx代理的连接。
-> 从Nginx代理到后端服务器的连接。

Nginx具有优化这些连接调整其行为的能力。
-> 如果没有缓冲,数据从代理的服务器发送并立即开始被发送到客户。如果假定客户端很快,缓冲可以关闭而尽快使数据到客户端.
-> 有了缓冲,Nginx代理将暂时存储后端的响应,然后按需供给数据给客户端。如果客户端是缓慢的,允许Nginx服务器关闭到后端的连接。然后,它可以处理数据分配到客户端,以任何可能的速度。

Nginx默认有缓冲设计,因为客户端往往有很大的不同的连接速度。可以用以下指令调节缓冲行为。可以在HTTP,server或location位置来设置。重要的是要记住,大小size指令是针对每个请求配置的,
所以增加超出你需求会影响你的性能,如果这时有许多客户端请求:
1)proxy_buffering:该指令控制缓冲是否启用。默认情况下,它的值是"on"。
2)proxy_buffers:该指令控制代理响应缓冲区的数量(第一个参数)和大小(第二个参数)。默认配置是8个缓冲区大小等于一个内存页(4K或者8K)。增加缓冲区的数目可以让你缓冲更多信息。
3) proxy_buffer_size:从后端服务器的响应头缓冲区大小,它包含headers,和其他部分响应是分开的。该指令设置响应部分的缓冲区大小。默认情况下,它和proxy_buffers是相同的尺寸,
   但因为这是用于头信息,这通常可以设置为一个较低的值。
4)proxy_busy_buffers_size:此指令设置标注"client-ready"缓冲区的最大尺寸。而客户端可以一次读取来自一个缓冲区的数据,缓冲被放置在队列中,批量发送到客户端。此指令控制允许是在这种状态下的缓冲空间的大小。
5)proxy_max_temp_file_size:这是每个请求能用磁盘上临时文件最大大小。这些当上游响应太大不能装配到缓冲区时被创建。
6)proxy_temp_file_write_size:这是当被代理服务器的响应过大时Nginx一次性写入临时文件的数据量。
7)proxy_temp_path:当上游服务器的响应过大不能存储到配置的缓冲区域时,Nginx存储临时文件硬盘路径。

Nginx提供了相当多不同的指令来调整缓冲行为。大多数时候不必担心太多,但它对于调整一些值可能是有用的。可能最有用的调整是proxy_buffers和proxy_buffer_size指令,比如:
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;
proxy_pass http://www.wang.com;

-----------------------------配置Nginx代理服务缓存来减少响应时间-----------------------------
尽管缓冲可以帮助释放后端服务器以处理更多的请求,Nginx还提供了一种方法来缓存从后端服务器的内容,对于许多请求无需连接到上游。
配置代理缓存,要设置缓存用于代理内容,可以使用proxy_cache_path指令。这将创建区域保存来自被代理服务器返回的数据。该proxy_cache_path指令必须在HTTP上下文部分进行设置。

比如下面的例子中,我们将配置一些相关的指令来建立缓存系统。
# http context
proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=backcache:8m max_size=50m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

用proxy_cache_path指令,首先应该已经定义在文件系统中希望存储缓存的目录。在这个例子中,选择在/var/nginx/cache目录。如果该目录不存在,可以用正确的权限和所有权创建它:
mkdir -p /var/nginx/cache
chown www /var/nginx/cache
chmod 700 /var/nginx/cache

levels=参数指定缓存将如何组织。 Nginx将通过散列键(下方配置)的值来创建一个缓存键。选择了上述的levels决定了单个字符目录(这是散列值的最后一个字符)配有两个字符的子目录
(下两个字符取自散列值的末尾)将被创建。你通常不必对这个细节关注,但它可以帮助Nginx快速找到相关的值。

keys_zone=参数定义缓存区域的名字,我们称之为backcache。这也是我们定义多少元数据存储的地方。在这个例子里,存储8MB的key。对于每兆字节,Nginx可存储8000左右的条目。
MAX_SIZE参数设置实际缓存数据的最大尺寸。

使用上面的另一个指令是proxy_cache_key。这个设置将设置用于存储缓存值的键。此键用于检查是否一个请求可以从高速缓存提供服务。将它设置成方案(http或https),HTTP请求方法,
以及被请求的主机和URI的组合。

proxy_cache_valid指令可以被指定多次。它依赖于状态代码值使我们能够配置多长时间存储。在我们的例子中,我们对于后端返回200和302存储10分钟,404响应的一分钟过期。

现在,已经配置了缓存区,但仍然需要告诉Nginx什么时候使用缓存。在代理到后端的location位置,我们可以配置使用这个缓存:
# server context
location /proxy-me {
proxy_cache backcache;
proxy_cache_bypass $http_cache_control;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_pass http://backend;
}

使用proxy_cache指令,就可以指定该backcache缓存区被用于这个位置。 Nginx会在这里检查传递给后端有效的条目。
上述proxy_cache_bypass指令被设置为$ http_cache_control变量。这将包含一个指示器,用以指示该客户端是否被明确地请求一个最新的,非缓存版本。设置此指令允许Nginx正确处理
这些类型的客户端请求。无需进行进一步的配置。

此外还增加了被称为X-Proxy-Cache的额外头,设置这个头部为$upstream_cache_status变量的值。这个设置头可以看到,如果请求导致高速缓存命中,高速缓存未命中,或者高速缓存被
明确旁路。这是对于调试特别有价值,也对客户端是有用的信息。

=========================关于缓存结果的注意事项================================
高速缓存能够极大地提高代理服务器的性能。不过,也需要明确的考虑配置缓存时候,要记住。
-> 首先,任何用户相关的数据不应被高速缓存。这可能导致一个用户的数据被呈现给其他用户。如果你的网站是完全静态的,这可能不是一个问题。
如果网站有一些动态元素,将不得不考虑到这一点。如何处理要看是什么应用程序或服务器处理的后端处理。
对于私人的内容,应该设置Cache-Control头为“no-cache”,“no-sotre”,或者“private”依赖于数据的性质:

no-cache:
请求: 告知缓存者,必须原原本本的转发原始请求,并告知任何缓存者,需要去转发请求,并验证缓存(如果有的话).对应名词:端对端重载.    
响应: 允许缓存者缓存副本.那么其实际价值是,总是强制缓存者,校验缓存的新鲜度.一旦确认新鲜,则可以使用缓存副本作为响应。no-cache,还可以指定某个包含字段,
      比如一个典型应用,no-cache=Set-Cookie. 这样做的结果,就是告知缓存者,对于Set-Cookie字段,你不要使用缓存内容.而是使用新滴.其他内容则可以使用缓存

no-store:表示在任何时候收到的数据不被缓存。这对于私人数据是最安全,因为它意味着,该数据必须从服务器每次进行检索。
private:这表明共享的缓存空间不能缓存此数据。这可以用于指示用户的浏览器高速缓存数据,但代理服务器不应当考虑随后的请求数据有效。
public:这表明该响应是可在连接的任何点被高速缓存的公共数据。

一个相关的可以控制此行为报头是max-age头,其指示,任何资源应该缓存的秒数。
根据内容的敏感性,正确设置这些头,会帮助你利用缓存优势,同时保持你的私人数据安全,并使您的动态数据最新。
如果后端也使用Nginx,你可以设置使用过期指令,设置max-age来实现Cache-Control:
location / {
expires 60m;
}

location /check-me {
expires -1;
}

在上面的例子中,第一个块允许缓存一个小时的内容。第二块设置Cache-Control头为“无缓存”。要设置其他值,可以使用add_header指令,就像这样:
location /private {
expires -1;
add_header Cache-Control "no-store";
}

                            本机缓存配置(80端口转8080,不使用ngx_cache_purge模块)                         

1)nginx正常编译安装(不需要ngx_cache_purge模块)。下载地址:http://nginx.org/en/download.html
[root@test ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc
[root@test ~]# cd /data/software
[root@test software]# tar zxvf nginx-1.10.3.tar.gz
[root@test software]# cd nginx-1.10.3
[root@test nginx-1.10.3]# ./configure --prefix=/data/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@test nginx-1.10.3]# make && make install
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx

[root@test nginx-1.10.3]# ls /data/nginx/
client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp

2) 进行cache缓存配置。缓存文件在tomcat程序里,即配置80代理到8080(tomcat程序端口)

[root@test nginx-1.10.3]# cat /data/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;

     upstream backend_servers {  
              server 127.00.0.1:8080;    
     }
  
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=mycache:500m inactive=1h max_size=30g;

    server {
        listen       80;
        server_name  localhost 192.168.1.19;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location = /apollo/1.html {
             root /usr/local/nginx/html;
        }

        location / {
           # root   html;
           # index  index.html index.htm;
            proxy_pass http://backend_servers;  
            
            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_cache mycache; 
            proxy_cache_valid  200 304  12h; 
            proxy_cache_valid any 1m;
                        client_max_body_size  100m;
        }

        #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 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

[root@test nginx-1.10.3]# mkdir /data/nginx/proxy_cache                  //创建上面配置中的cache目录,注意:这里只是配置了一个cache路径,temp路径采用默认的。 
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx -t
nginx: the configuration file /data/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /data/nginx/conf/nginx.conf test is successful
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx -s reload

==============缓存效果测试===============

有上面可以看出,80代理到8080的配置已经生效!下面看下缓存文件是否生成:

[root@test nginx-1.10.3]# ll /data/nginx/
total 40
drwx------ 2 nginx root 4096 Sep 1 17:54 client_body_temp
drwxr-xr-x 2 root root 4096 Sep 1 20:22 conf
drwx------ 2 nginx root 4096 Sep 1 17:54 fastcgi_temp
drwxr-xr-x 2 root root 4096 Sep 1 17:54 html
drwxr-xr-x 2 root root 4096 Sep 1 18:30 logs
drwxr-xr-x 6 nginx root 4096 Sep 1 20:22 proxy_cache
drwx------ 10 nginx root 4096 Sep 1 20:24 proxy_temp
drwxr-xr-x 2 root root 4096 Sep 1 18:01 sbin
drwx------ 2 nginx root 4096 Sep 1 17:54 scgi_temp
drwx------ 2 nginx root 4096 Sep 1 17:54 uwsgi_temp
[root@test nginx-1.10.3]# ll /data/nginx/proxy_cache/
total 16
drwx------ 3 nginx nginx 4096 Sep 1 20:22 2
drwx------ 4 nginx nginx 4096 Sep 1 20:22 7
drwx------ 3 nginx nginx 4096 Sep 1 19:48 8
drwx------ 3 nginx nginx 4096 Sep 1 19:48 f
[root@test nginx-1.10.3]# ll /data/nginx/proxy_temp/            #默认的temp目录
total 32
drwx------ 3 nginx nginx 4096 Sep 1 19:48 1
drwx------ 3 nginx nginx 4096 Sep 1 19:48 2
drwx------ 3 nginx nginx 4096 Sep 1 19:48 3
drwx------ 3 nginx nginx 4096 Sep 1 20:22 4
drwx------ 3 nginx nginx 4096 Sep 1 20:22 5
drwx------ 3 nginx nginx 4096 Sep 1 20:22 6
drwx------ 3 nginx nginx 4096 Sep 1 20:23 7
drwx------ 3 nginx nginx 4096 Sep 1 20:24 8

可以看出,缓存文件已经生成!要是清理缓存的话,就清空上面两个目录即可!
========================================================================

再看下结合purge模块的缓存配置:
[root@storage01 ~]# cat /data/nginx/conf/nginx.conf
#user  nobody;
worker_processes  4;
   
events {
    worker_connections  65535;
}
   
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
  
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
  
    proxy_temp_path /data/nginx/proxy_temp;
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=mycache:500m inactive=1d max_size=30g;
      
    client_header_timeout 600s;
    client_body_timeout 600s;
   
    client_max_body_size 50m;            
    client_body_buffer_size 256k;          
   
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
   
    include vhosts/*.conf;
}


[root@storage01 ~]# mkdir proxy_cache
[root@storage01 ~]# mkdir proxy_temp
[root@storage01 ~]# chown -R nginx.nginx proxy_cache
[root@storage01 ~]# chown -R nginx.nginx proxy_temp
[root@storage01 ~]# chmod -R 777 proxy_cache
[root@storage01 ~]# chmod -R 777 proxy_temp


[root@storage01 ~]# cat /data/nginx/conf/vhosts/cache.conf 
upstream backend_servers {  
              server 127.0.0.1:8080;    
     }

server {
        listen       80;
        server_name  localhost 192.168.1.25;

        access_log  /data/nginx/logs/80-access.log main;
        error_log  /data/nginx/logs/80-error.log;


        location / {
           # root   html;
           # index  index.html index.htm;
            proxy_pass http://backend_servers;  
            
            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_cache mycache; 
            proxy_cache_valid  200 304  12h; 
            proxy_cache_valid any 1m;
            proxy_cache_key $host$uri$is_args$args;

        }

        #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;
        }

        location ~ /purge(/.*) {
           allow all ;
           proxy_cache_purge mycache $host$1$is_args$args ;
           error_page 405 =200 /purge$1;
        }
}


访问http://192.168.1.25/storage/   反向代理到 http://192.168.1.25:8080/storage/

清理缓存的正确方式:http://192.168.1.25/purge/storage/
posted @ 2016-12-19 17:25  散尽浮华  阅读(...)  评论(... 编辑 收藏