利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

阅读数:89 2019 年 9 月 25 日 15:55

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

1. 背景和挑战

随着国内互联网媒体企业纷纷选择出海拓展业务,如何提高海外终端用户的用户体验成为各个企业重点关注内容,CloudFront 是 AWS 的网络分发(CDN)服务,很多企业选择使用 AWS S3 服务作为静态内容持久存储源并利用 CloudFront 服务分布在全球各地的边缘站点进行资源分发,这样可以大大提高终端用户的使用体验。实际情况中,许多媒体企业海外业务并不完全独立于国内业务,例如:媒体制作,视频转码,内容合规性的检查等服务都依赖于国内资源。而不同的海外地区频繁访问的内容也不尽相同,所以通常国内源站存储全量资源,海外存在多个源站存储当地热点资源。那如何将国内源站的哪些资源同步到海外的哪个源站就成为一个必须解决的问题。面对这个问题需要从实际使用情况出发,真实的本地终端客户访问的资源才是需要存储到本地源站的资源。面对这种场景,出海企业需要一个解决方案能够根据真实客户需求动态将国内源站内容补充到海外源站中。

2. 架构设计

在海外 AWS 指定 region 部署 S3 作为主源站,存储该地区热点数据。
在国内用户可以部署自己的源站应用服务。

  • 当海外用户访问某一些资源,在 CloudFront 缓存不存在且海外源站 S3 中也不存在此资源文件时,需要将该请求回源到国内源站,并同时触发一个 Lambda@edge 并行进行补充该资源文件到海外源站。
  • 为了不影响终端用户的使用体验,使用 SQS 将终端请求与补源操作进行解耦。在 SQS 消费端创建一个事件触发的 Lambda 处理函数,此函数进行资源的补齐。
    整体结构设计和流程图如下所示。
    利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

3. 部署和配置

环境准备:海外源站为在 AWS 外海指定区域部署的 S3 存储桶,用于持久化存储本地常访问的资源,使用 ALB+WebApp 作为国内全量源站。在本实验中这两个环境已经提前创建完毕。

  • S3 存储桶信息: xinranl-static.s3.amazonaws.com
  • ALB 信息: TestALB-XXXXXXX.elb.amazonaws.com
    1)创建 CloudFront 分发,将 S3 存储桶作为默认源站。由于我们所创建的存储桶为私有的,所以需要在创建分发的时候需要有一个源访问身份。如果您之前已经创建过分发并且创建过源访问身份可以在这里复用,如果没有可以在这里选择创建新身份。在授予对存储桶的读取权限项选择“是,更新存储桶策略”。
    利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

当创建完成分配后,我们可以在该分配的“源和源组”中看到刚刚指定的源站。

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

2)创建全量源站,将 ALB 作为新的源站。
利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

3)然后创建源站组,将 S3 作为主源站,将 ALB 作为备源站。将故障转移条件全部勾选上。

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源
4)更新行为的“源与源组信”信息,在分配中的“行为“选项栏中,编辑行为,将源和源组配置为刚刚我们创建的源组。

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源
5)创建 SQS 队列。创建标准 SQS 队列 SyncSourceTaskQueue,记录队列信息。
利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

6)创建 Lambda 触发器函数。为此函数添加触发器,当请求回源的时候才触发此函数。触发器配置选择 CloudFront, 分配选择刚刚我们创建的 CloudFront 分配,请求选择“源请求”。
利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

该函数主要逻辑是:当一个请求没有在缓存中命中,请求会回到源站,此时会触发该函数。函数判断请求是回到哪个源站,如果回到 S3 源站此函数忽略处理,如果请求是回到 ALB 源站说明请求资源在 S3 源站中没有,需要触发补源流程,此函数将会把请求内容信息发送到 SQS 队列中,通知后续补源处理。此函数代码实现如下:
利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

代码段:

复制代码
var onlyhttp = require('http');
const fs = require('fs')
var AWS = require('aws-sdk');
var sqs = new AWS.SQS();
exports.handler = (event, context, callback) => {
console.log('event: ',JSON.stringify(event));
const response = event.Records[0].cf.response;
if (event.Records[0].cf.request.headers.host[0].value == 'xinranl-static.s3.amazonaws.com'){
callback(null, response);
}
var body = event.Records[0].cf.request.uri;
var params = {
MessageBody: body,
QueueUrl: 'https://sqs.us-east-1.amazonaws.com/XXXXX/Sync_source_queue'
};
sqs.sendMessage(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
callback(null, response);
};

7)Lambda 补源函数,将本地源站不存在的内容从全量源站补充过去。创建 Lambda 函数,并为其增加触发器,触发配置选择 SQS,SQS 队列选择刚刚我们创建的队列 ARN。

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源
该函数主要逻辑是:SQS 队列不为空的时候,队列里面每一个消息会触发一个 Lambda 函数。该 Lambda 函数会从 SQS 消息体得到要补充的资源信息,并发送获取请求到全量源站,之后再将获取到的数据发送到需要补充到的海外源站中。
利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

代码段:

复制代码
var onlyhttp = require('http');
const fs = require('fs')
var AWS = require('aws-sdk');
var sqs = new AWS.SQS();
exports.handler = (event, context, callback) => {
console.log('event: ',JSON.stringify(event));
const response = event.Records[0].cf.response;
if (event.Records[0].cf.request.headers.host[0].value == 'xinranl-static.s3.amazonaws.com'){
callback(null, response);
}
var body = event.Records[0].cf.request.uri;
var params = {
MessageBody: body,
QueueUrl: 'https://sqs.us-east-1.amazonaws.com/XXXXX/Sync_source_queue'
};
sqs.sendMessage(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
callback(null, response);
};

4.验证步骤

  • 在自动补源前 S3 源站中并不存在测试资源 images/shared/video.mp4

利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

  • 用户可以直接通过 ALB 获取媒体资源,判断该资源是否真实存在。

  • 终端用户可以通过 CloudFront 分配的公网域名访问该媒体资源。此请求会触发自动补源流程。
    d29f62eg8qfefw.cloudfront.net/images/shared/video.mp4

  • 补源流程完成时间跟网络状况与文件大小有关,在整个流程完成后,我们可以看到 S3 中已经出现最新补充的资源信息。
    利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源

相关文章:
[1]CloudFront 开发人员指南:
https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/Introduction.html

[2]SQS 开发人员指南:
https://docs.aws.amazon.com/zh_cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.htmlhttps://docs.aws.amazon.com/zh_cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html

[3]Lambda 开发与部署:

https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/getting-started-create-function.html

作者介绍:

刘欣然
AWS 解决方案架构师, 目前负责互联网媒体行业云端应用的架构设计与技术咨询。在加入 AWS 之前从事多年互联网开发工作,目前专注于 Devops 与边缘计算领域。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/lambda-sqs-dynamic-cloudfront-abraod-resources/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布