利用nginx cache緩存網站數據
nginx本身就有緩存功能,能夠緩存靜態對象,比如圖片、CSS、JS等內容直接緩存到本地,下次訪問相同對象時,直接從緩存即可,無需訪問后端靜態服務器以及存儲存儲服務器,可以替代squid功能。
1環境准備
我們這里只測試nginx的proxy_cache的緩存功能,所以結構越簡單越好,這里我們只需要准備一台nginx的虛擬機即可,如果沒有nginx,那么我們可以使用epel源,yum安裝一個即可:
#添加epel源
root@~>> wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
#yum安裝nginx
root@~>> yum install nginx -y
#rpm -ql查看主要配置文件位置
root@~>> rpm -ql nginx
這里為了簡單,只使用簡單的nginx.conf配置文件:
root@nginx>> cat nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_formatmain '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
啟動查看初始界面是否正常:
root@nginx>> nginx
root@nginx>> netstat -tupln|grep nginx
tcp 00 0.0.0.0:800.0.0.0:* LISTEN 1043/nginx
root@nginx>> curl -I 192.168.16.199
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Mon, 14 Sep 2015 09:40:53 GMT
Content-Type: text/html
Content-Length: 3698
Last-Modified: Tue, 16 Jun 2015 21:34:15 GMT
Connection: keep-alive
Accept-Ranges: bytes
一切正常,首頁有2張圖片,正好用於實驗:
root@html>> tree /usr/share/nginx/html/
/usr/share/nginx/html/
|-- 404.html
|-- 50x.html
|-- index.html
|-- nginx-logo.png
`-- poweredby.png
至此環境准備完畢。
2cache原理
3配置cache
3.1創建目錄並掛載tmpfs
nginx的proxy_cache是基於內存和磁盤的緩存,需要指定緩存目錄:
root@nginx>> mkdir /tmp/ngx_cache -p
緩存存放於磁盤,磁盤IO會影響緩存的速度,所以我們在將tmpfs掛載於ngx_cache目錄上來加速緩存的讀取和寫入:
root@nginx>> mount -t tmpfs -o size=100M tmpfs /tmp/ngx_cache
root@nginx>> mount|grep tmpfs
tmpfs on /dev/shm type tmpfs (rw)
tmpfs on /tmp/ngx_cache type tmpfs (rw,size=100M)
3.2配置緩存目錄大小以及key空間名
將下面配置放至http標簽中:
root@nginx>> grep proxy_cache_path nginx.conf
proxy_cache_path /tmp/ngx_cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=5g;
#指定緩存目錄,緩存等級,鍵空間名,鍵空間shm大小,失效時間,以及磁盤最大緩存大小
3.3配置反向代理
首先配置upstream節點池:
upstream server_pool {
server 127.0.0.1:8080;
}
在server標簽的location段中配置代理:
proxy_pass http://server_pool;
配置8080端口的標簽:
server {
listen 8080;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
access_log/var/log/nginx/access.log main;
}
配置proxy_cache相關參數啟用緩存:
proxy_pass http://server_pool;
proxy_next_upstream http_502 http_504 error timeout invalid_header; #出錯嘗試下一個節點
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; #指定鍵key的格式
proxy_set_header Host $host; #傳遞主機名給后端節點
proxy_set_header X-Forwarded-For $remote_addr; #傳遞客戶端IP給后端節點
expires 1d; #超期時間
最終的nginx.conf配置文件如下:
root@nginx>> cat nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_formatmain '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"addr:$upstream_addr-status:$upstream_status- cachestatus:$upstream_cache_status"';
sendfile on;
keepalive_timeout 65;
proxy_cache_path /tmp/ngx_cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=5g;
upstream server_pool {
server 127.0.0.1:8080;
}
server {
listen 80;
location / {
proxy_pass http://server_pool;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
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;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
expires 1d;
}
access_log /var/log/nginx/cache_access.log main;
}
server {
listen 8080;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}
3.4配置日志
為了觀察緩存的命中狀態,我們可以將緩存相關的變量記錄在日志中。
定義日志格式:
log_format main'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"addr:$upstream_addr-status:$upstream_status- cachestatus:$upstream_cache_status"';
#其中upstream_addr記錄分發的后端節點IP;upstream_status記錄后端節點返回的狀態碼;upstream_cache_status記錄緩存的命中情況。
在反向代理標簽中引用日志:
access_log/var/log/nginx/cache_access.logmain;
nginx重新加載配置:
root@nginx>> nginx -s reload
3.5添加頭信息查看
添加響應報頭信息:
add_header X-Cache-Status $upstream_cache_status;
查看頭信息:
root@~>> curl -I 192.168.16.199
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Tue, 15 Sep 2015 02:55:25 GMT
Content-Type: text/html
Connection: keep-alive
Content-Length: 3698
Last-Modified: Tue, 16 Jun 2015 21:34:15 GMT
Expires: Wed, 16 Sep 2015 02:55:25 GMT
Cache-Control: max-age=86400
X-Cache-Status: HIT
Accept-Ranges: bytes
3.6監測緩存
為了監測緩存文件的事件,我們首先安裝inotify-tools:
root@/>> yum install inotify-tools
打開一個ssh使用intofiy-tools檢測ngx_cache目錄:
root@~>> inotifywait -mrq /tmp/ngx_cache/
瀏覽網站:
root@ngx_cache>> inotifywait -mrq /tmp/ngx_cache/
/tmp/ngx_cache/ CREATE,ISDIR 6
/tmp/ngx_cache/ OPEN,ISDIR 6
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 6
/tmp/ngx_cache/ CREATE,ISDIR 1
/tmp/ngx_cache/ OPEN,ISDIR 1
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 1
/tmp/ngx_cache/ CREATE,ISDIR 3
/tmp/ngx_cache/ OPEN,ISDIR 3
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 3
/tmp/ngx_cache/3/ CREATE,ISDIR fd
/tmp/ngx_cache/3/ OPEN,ISDIR fd
/tmp/ngx_cache/3/ CLOSE_NOWRITE,CLOSE,ISDIR fd
/tmp/ngx_cache/3/fd/ CREATE dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ OPEN dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MODIFY dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ CLOSE_WRITE,CLOSE dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MOVED_FROM dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MOVED_TO dd404cd351f6b9efb072e5806dc2efd3
說明:有最后幾行可知,圖片緩存到目錄中。
3.7查看hash對比
添加日志項:
'"KEY:$host$uri$is_args$args"'
重啟查看日志項:
192.168.16.1 - - [15/Sep/2015:10:41:23 +0800] "GET /nginx-logo.png HTTP/1.1" 200 368 "http://192.168.16.199/" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0" "-""addr:--status:-- cachestatus:HIT""KEY:192.168.16.199/nginx-logo.png-"
計算MD5:
root@~>> echo -n "192.168.16.199/nginx-logo.png"|md5sum
6a6e2e4e3251b1aae0488859ed38e7b1 -
緩存文件:
/tmp/ngx_cache/1/7b/ ACCESS 6a6e2e4e3251b1aae0488859ed38e7b1
同時觀察三個標紅的,之前我們設置了levels=1:2,相當於小抽屜,和memcached的slab以及trunk類似。