我创建了一个 Lambda 函数,它从 DynamoDB 检索一些数据,它会输出一些 JSON。我想要做的是在 lambda@edge 中运行这个函数并生成一个我可以使用 Cloudfront 缓存的响应。
我面临的问题是,我在 DynamoDB 中的数据使用全局表在(当前)两个区域(us-east-2 和 eu-west-1)中复制,而 lambda@edge 显然在许多区域中运行。
这使我无法AWS_REGION
从 lambda 环境中使用。例如,如果一个请求在 us-west-1 中运行,环境变量会反映这一点,并且它会尝试从 us-west-1 检索数据,它实际上应该去往 us-east-2。
虽然我承认我还没有尝试过这个(还),但我想知道是否可以在 Route53 中设置我自己的基于延迟的路由,将 ddb.mydomain.com 指向我使用的区域中 DynamoDB 的端点,假设 SAN 证书已设置起来它会工作吗?
我想也许我可以按照下面的示例在代码中映射区域
const process = { env: { AWS_REGION: 'us-east-1' } };
const regions = {
'eu-west-1': ['eu-west-1', 'eu-central-1', '...'],
'us-east-2': ['us-west-1', 'us-east-1', '...'],
};
const activeRegions = Object.keys(regions);
const region = activeRegions.find(
key => regions[key].includes(process.env.AWS_REGION)
) || activeRegions[0];
console.log(region) // us-east-2
这感觉就像它的维护比它的价值更多,并且依赖于我对最佳选择区域的假设。我还必须更新我的地区列表。
当新数据中心稍微开放时,我可以只使用该区域的前两个字母来限制更新它的需要,但这仍然不理想
const process = { env: { AWS_REGION: 'ca-central-1' } };
const regions = {
'eu-west-1': ['eu', 'sa', 'ap', '...'],
'us-east-2': ['us', 'ca', 'sa', '...'],
};
const activeRegions = Object.keys(regions);
const key = activeRegions.find(
key => regions[key].includes(
process.env.AWS_REGION.substring(0, 2) // Just the first 2 letters
)
) || activeRegions[0];
console.log(key); // us-east-2
我怀疑我遗漏了一些明显的东西,这可能使我能够从 lambda@edge 明智地选择我的数据所在的区域。
编辑
从那以后我发现了这个,一个已被删除的 aws lambda@edge 研讨会,它提出了与上述类似的方法。为什么它被删除我不知道。
function updateDynamoDbClientRegion(request) {
let region;
// Check if viewer country header is available
if (request.headers['cloudfront-viewer-country']) {
const countryCode = request.headers['cloudfront-viewer-country'][0].value;
region = countryToRegionMapping[countryCode];
}
// Update DynamoDB client with nearer region
if (region) {
ddb = ddbUS;
}
}
该研讨会的自述文件现在只是讨论了使用全局表来减少延迟的选项,但没有提供关于如何选择最接近的具有数据的表的见解。
编辑 2
我从 cloudping 中获取了延迟数据的副本,并将以下要点拼凑在一起,现在可以使用。
https://gist.github.com/benswinburne/06a00fab330dca93ea6df2552f73850a
这样做的缺点显然是数据陈旧。不幸的是,cloudping 的 api 对于此目的还不够快,一旦我去远程资源获取最新数据,我还不如去任何地区的 DynamoDB 表¯\_(ツ)_/ ¯