小计 -- 使用AWS CloudFront(CDN)的使用及对国内的优化

最近,使用AWS云服务,在上面安装了一个静态网站,主要是给国外用户访问,但在国内的老板们也要看。使用了AWS的EC2 + CloudFront方式 , 因为是纯静态的网站。虽然是一个很简单的事情,但在使用当中,还是碰到了一些小问题,所以备注一下。

网站在AWS上的结构

先说一下这个网站的需求:
首先,这个网站是给老外用的
其次,这是一个静态网站,而且可能会有突发的大访问量
再次,这个网站在国内的老板们也要看,国内访问也不能太慢
所以,使用AWS的 CloudFront(CDN) + EC2 (源站)), CloudFront 选择了全球加速(Price Class), EC2 的位置放在了us-west-1,这个位置从国内访问还算凑合。 我们设置在AWS上网站结构如下图:

为什么要到把国内用户的访问直接指向EC2而不是CloudFront?
经过我们测试下来,从国内访问CloudFront比直接访问EC2(us-west-1)要慢2~3倍,而且国内不会有突发的访问量。

CloudFront 设置注意事项有

  1. 如果你是使用S3做为源站(一开始我是准备这么做的) ,请记得把S3的公共访问打开,不然在CloudFront上无法访问到内容。
  2. 如果使用EC2做为源站的话,在设置Origin的Origin Domain Name时,因为只接受域名,可以使用EC2在AWS上的域名,每个EC2实例都有。
  3. 在Edit Distribution设置中,记得在 alternate Domain Names中加入站点对外的名称,在我这里,是www.mysite.com
  4. 设置 Default Root Object 为index.html,做这个设置,是为了在清缓存时有作用,如果你在清缓存时,根据用户上传文件列表,只清了/index.html而没有清/,那你会发现缓存没有清完成。
  5. Cache Behavior Settings非常重要,我做了下面几点的更改:
    • 在Object Caching中,使用默认的Use Origin Cache Headers 这样做的好处是,可以源上(EC2的Nginx)上增加配置你的缓存策略,Nginx上的策略,后面具体说明。
    • Query String Forwarding and Caching 我选择了Forward all ,因为我的站点会有一些?参数的链接,但后面的参数是固定的,可以缓存。这个设置因情况各不同。
    • Compress Objects Automatically 我设置为yes,使用压缩可以大大减小js和css的大小。

我的网站上Nginx的缓存策略

上面说了,我让CloudFront 使用我的缓存策略,而这个缓存策略是可以在nginx上设置的。下面是我的nginx的缓存设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
### 设置图片缓存30天
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
access_log off;
expires 30d;
}
### 设置css js 缓存24h
location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
access_log off;
expires 24h;
}
### 设置字体文件永久缓存,为什么?因为老外喜欢用google字体
location ~* ^.+\.(eot|ttf|otf|woff|svg)$ {
access_log off;
expires max;
}

有了缓存,就会有清缓存的需求,如果你没有用CMS话

是的,这个静态网站没有用CMS,所以要进行缓存清除,这个操作人来做的话,真是没意思,所以我把它做成自动的。每5分钟check一下ftp上传日志是否有更新,如果有更新内容,就在日志中找出更新的文件名列表,然后用aws cli给invalidate掉。

  • 先给一个清缓存的脚本,当然首先你要安装 aws cli工具,然后要有操作你的cloudfront的权限的credentials:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/bin/bash
    #Useage: This script is used to read upload file list from /opt/log/vsftpd.log and invalidate files in CloudFront

    ### echo a run time
    echo "=============== at `date +%Y%m%d%H%M` do aws cloudfront invalidation =============="
    ### get upload file list from vsftpdlog
    upload_files=$(diff /opt/log/vsftpd.log /opt/log/vsftpd.log.old | grep -v .git-ftp.log | grep `date +%Y` | awk '{print $10}' |sort -u | tr '\n' ' ')
    cp /opt/log/vsftpd.log /opt/log/vsftpd.log.old
    echo "========== upload files =========="
    echo "${upload_files}"
    ### if have upload_files do aws invalidation
    if [ "$upload_files" != "" ]; then
    aws cloudfront create-invalidation --distribution-id your-distribution-id --paths ${upload_files}
    else
    echo "No upload files, need not to invalidate CloudFront cache"
    fi
  • 把这个脚本加到crontab中,实现自动check ,自动cache invalidate

    1
    2
    ### automatic invalidate CloudFront cache when files were uploaded
    */5 * * * * bash ~/aws_cloudfront_pure_file.sh >> ~/aws_cloudfront_pure_file.log 2>&1
坚持原创技术分享,您的支持将鼓励我继续创作!