最近,使用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对国内用户的优化,那就不用再看下去了,最简单的方法,就是弃用CloudFront,哈哈。
CloudFront 设置注意事项有
- 如果你是使用S3做为源站(一开始我是准备这么做的) ,请记得把S3的公共访问打开,不然在CloudFront上无法访问到内容。
- 如果使用EC2做为源站的话,在设置Origin的Origin Domain Name时,因为只接受域名,可以使用EC2在AWS上的域名,每个EC2实例都有。
- 在Edit Distribution设置中,记得在 alternate Domain Names中加入站点对外的名称,在我这里,是www.mysite.com
- 设置 Default Root Object 为index.html,做这个设置,是为了在清缓存时有作用,如果你在清缓存时,根据用户上传文件列表,只清了/index.html而没有清/,那你会发现缓存没有清完成。
- 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