使用Nginx反向代理做cache缓存-实现CDN功能

目标

使用Nginx反向代理做cache缓存-实现CDN功能

环境

192.168.56.11是CDN节点
192.168.56.12是资源源站

源站nginx配置

源站nginx配置:
yum install -y nginx
hostnamectl set-hostname linux-node2
echo "This is linux-node2" >/usr/share/nginx/html/index.html
端口修改为8080
nginx -t
systemctl status nginx

要求:能正常使用curl请求访问资源。
curl -H "Host:www.exmail.com" http://192.168.56.12:8080

CDN节点-配置

CDN节点nginx配置:
yum install -y nginx
cd /etc/nginx/conf.d

配置nginx

vim www.example.com.conf

server
{
    listen 80;
    server_name www.example.com;
    access_log /var/log/nginx/www.example.com-access.log main;
    ##给这些静态资源做缓存
    location ~ .*\.(gif|jpg|png|html|htm|css|js|ico|swf|pdf)$ {
    #Proxy 
    proxy_redirect off;
        proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
        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_pass    http://www.example.com.pool;

    #Use Proxy Cache
    proxy_cache cache_one;   #定义的缓存池名称
    proxy_cache_key "$host$request_uri";   #定义缓存存放目录的子目录命名规则
    add_header Cache "$upstream_cache_status"; #缓存的HTTP头部加了一个Cache
    proxy_cache_valid  200 304 301 302 8h;
    proxy_cache_valid 404 1m;
    proxy_cache_valid  any 2d;
    }


    #回源区,如果上面的location没有命中,则使用下面的配置访问源站信息
    location /
    {
          proxy_redirect off;
          proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
          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_pass    http://www.example.com.pool;
          client_max_body_size 40m;
          client_body_buffer_size 128k;
          proxy_connect_timeout 60;
          proxy_send_timeout 60;
          proxy_read_timeout 60;
          proxy_buffer_size 64k;
          proxy_buffers 4 32k;
          proxy_busy_buffers_size 64k;

   }
}

配置upstream

vim upstrem.conf

upstream www.example.com.pool
{
        server 192.168.56.12:8080 weight=10 max_fails=3;      #可以添加多个
}

配置CDN

创建CDN缓存存放目录

mkdir -p /data/cdn_cache/

vim proxy.conf

#CDN
#临时缓存目录
proxy_temp_path /data/cdn_cache/proxy_temp_dir; 
#真实缓存存放目录(其中cache_one是定义的一个缓存区域名称)
proxy_cache_path /data/cdn_cache/proxy_cache_dir levels=1:2 keys_zone=cache_one:50m inactive=1d max_size=1g;
proxy_connect_timeout 5;
proxy_read_timeout 60;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404;
配置检查
nginx -t

启动服务
systemctl status nginx

测试

CDN节点访问:
[root@linux-node1 nginx]# curl -H "Host:www.exmail.com" http://192.168.56.11/index.html
this is linux-node2


[root@linux-node1 nginx]# tree /data/cdn_cache
/data/cdn_cache
├── proxy_cache_dir
│   ├── b
│   │   └── ec
│   │       └── abe4950dded0468475eb27f43c676ecb
│   └── d
│       └── 3e
│           └── 9f4970c1daafbbba52d6e625e05f23ed
└── proxy_temp_dir

本地浏览器访问:
添加host解析,网页访问测试。http://www.example.com/index.html
我们使用firebug看看HTTP请求头部信息,当出现了"Cache HIT"说明已经命中。如果出现:Cache    
MISS说明没有被缓存命中。
注:CDN缓存目录数据存放规则:
cd /data/cdn_cache/proxy_cache_dir/    #进入实际缓存目录
cd ./d/3e目录
cat 9f4970c1daafbbba52d6e625e05f23ed 
    "59bdf88c-14"
    KEY: www.exmail.com/index.html   
    HTTP/1.1 200 OK
#注:md5sum加密的是"www.exmail.com/index.html"字符,此处的key值定义规则在www.example.com.conf配置文件中的proxy_cache_key "$host$request_uri";

注:proxy_buffering 不能为off,否则无法缓存指定内容


目录命名规则:
/data/cdn_cache/
├── proxy_cache_dir
│   ├── 6
│   │   └── e1
│   │       └── 8ef7ececfe8528bffb1d8ae1f639ce16

1. 将用户访问的URL进行md5sum加密,然后取第一列,假设为:8ef7ececfe8528bffb1d8ae1f639ce16
2. 第一级目录是倒数第一位数字命名,此处为:6
3. 第二级目录是倒数第1位和第2位数字命名,此处为:e1

CDN删除缓存-脚本

#!/bin/bash

cache_purge(){
PURGE_URL=$1
    URL_NAME=$(echo -n $PURGE_URL | md5sum | awk '{print $1}')
    FILE_NAME=$(echo $URL_NAME  | awk '{print "/data/cdn_cache/proxy_cache_dir/"substr($0,length($0),1)"/"substr($0,length($0)-2,2)"/"$0}')
    rm -rf $FILE_NAME 
}

purge_file(){
PURGE_FILE=$1
for url in $(cat $PURGE_FILE);do
cache_purge $url
done
}

purge_url(){
PURGE_URL=$1
cache_purge $PURGE_URL
}

usage(){
echo $"Usage: $0 <url_file | 'url'>"
}

main (){
if [ "$#" -ne 1 ];then
usage;
else
if [ -f $1 ];then
purge_file $1;
else
purge_url $1;
fi
fi
}

main $1

使用

chmod +x nginx_refresh
./nginx_refresh www.example.com/index.html

第三方清除缓存

第三方扩展模块ngx_cache_purge,编译安装可实现清除缓存
https://www.lvtao.net/web/nginx-cache-purge.html 

排错

1.检查源站是否能够正常访问
2.检查CDN节点是否能够正常访问源站
3.检查CDN节点端口
4.检查CDN节点服务
5.检查CDN节点日志
6.用户到CDN节点之间是否正常

分布式缓存架构-现状

Nginx + Varnish CDN
Nginx + Lua
Nginx + ATS(主流架构方式)

发表评论