CDN 简介

什么是 CDN

为了解决互联网上越来越多内容的传输、存储、分发等问题,提供给终端用户更好的访问和使用体验,CDN 便是一个高性价比,操作便捷,快速实现的解决方案。CDN(Content Delivery Network),是在现有 Internet 中增加一层新的网络架构,由遍布全国的高性能加速 节点构成。这些高性能的服务节点都会按照一定的缓存策略存储您的业务内容,当您的用户 向您的某一业务内容发起请求时,请求会被调度至最接近用户的服务节点,直接由服务节点 直接快速响应,有效降低用户访问延迟,提升可用性。

CDN 的基本原理

假设您的业务源站域名为 www.test.com ,当域名接入 CDN 开始使用加速服务后,您
的用户发起 HTTP 请求,实际的处理流程如图所示:
图 1 CDN 基础流程示意图

详细说明如下:

  • 用户向 www.test.com 下的某图片资源,如 1.jpg 发起请求,先要向 Local DNS 发起域名解析请求;
  • 当 Local DNS 解 析 www.test.com 时 , 会 发 现 已 经 配 置 了 CNAME www.test.com.cdn.dnsv1.com,解析请求会发送至 Tencent DNS(GSLB),GSLB 为腾讯云自主研发的调度体系,会为请求分配最佳节点 IP;
  • Local DNS 获取 Tencent DNS 返回的解析 IP;
  • 用户测获取解析 IP;
  • 用户向获取的 IP 发起对资源 1.jpg 的访问请求;
  • 若该 IP 对应的节点缓存有 1.jpg,则会将数据直接返回给用户(10),此时请求结束。若该节点未缓存 1.jpg,则节点会向业务源站发起对 1.jpg 的请求(6、7、8),获取资源后,结合用户自定义配置的缓存策略(可参考用户指南中缓存时间设置章节内容),将资源存储(9),并返回给用户(10),此时请求结束。

可以使用哪些开源软件自建 CDN

Nginx,Varnish,Squid,Apache Traffic Server,Fikker,WDCDN 等软件/系统都可以实现 CDN 的功能。本文将使用 Nginx 来实现一个简易的 CDN 系统。

使用 Nginx 搭建简易 CDN

开启代理缓存

proxy_temp_path /data/cdn_cache/proxy_temp_dir;
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;

配置上游服务器

upstream www.example.com.pool
{
    server www.example.com weight=10 max_fails=3;
}

配置反向代理

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 https://www.example.com.pool;

        #Use Proxy Cache
        proxy_cache cache_one;
        proxy_cache_key "$host$request_uri";
        add_header Cache "$upstream_cache_status";
        proxy_cache_valid  200 304 301 302 8h;
        proxy_cache_valid 404 1m;
        proxy_cache_valid  any 2d;
    }
    
    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;
   }
}

缓存刷新

编写一个简单的 Shell 脚本来实现缓存刷新的功能,用法:./nginx_purge.sh URL

#!/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

存在问题

  • 不能刷新目录

标签: Nginx, CDN

添加新评论