如何用Node.js SDK的AWS Lambda函数发起Glacier检索任务并返回存档URL?
使用Node.js SDK编写AWS Lambda处理Glacier存档检索
Glacier的存档检索是异步操作,无法立即获取下载URL,流程分为两步:发起检索任务 → 等待任务完成(通常1-5小时,取决于检索类型)→ 获取已完成任务的下载URL。下面是具体实现步骤和代码:
1. 配置Lambda的IAM权限
给Lambda执行角色添加以下权限(通过IAM策略配置):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "glacier:InitiateJob", "glacier:GetJobOutput", "glacier:DescribeJob" ], "Resource": "arn:aws:glacier:你的区域:你的账号ID:vaults/你的vault名称" } ] }
2. 发起检索任务的Lambda代码(Node.js SDK v3)
这个函数负责触发Glacier的检索任务,返回任务ID供后续查询:
import { GlacierClient, InitiateJobCommand } from "@aws-sdk/client-glacier"; const client = new GlacierClient({ region: "你的AWS区域" }); const vaultName = "你的Glacier Vault名称"; export const handler = async (event) => { // 从请求参数中获取存档ID const archiveId = event.queryStringParameters?.archiveId; if (!archiveId) { return { statusCode: 400, body: JSON.stringify({ error: "缺少存档ID(archiveId)" }) }; } // 构建检索任务参数,可选类型:Expedited(快速)/Standard(标准)/Bulk(批量) const params = { vaultName: vaultName, jobParameters: { Type: "archive-retrieval", ArchiveId: archiveId, Description: "Lambda发起的存档检索任务", // 可选:配置SNS主题,任务完成时自动通知 // SNSTopic: "arn:aws:sns:你的区域:你的账号ID:你的SNS主题" } }; try { const command = new InitiateJobCommand(params); const response = await client.send(command); return { statusCode: 202, body: JSON.stringify({ jobId: response.jobId, message: "检索任务已发起,预计1-5小时完成,可使用jobId查询状态" }) }; } catch (err) { return { statusCode: 500, body: JSON.stringify({ error: err.message }) }; } };
3. 查询任务状态并获取下载URL的Lambda代码
当任务完成后,调用这个函数生成预签名下载URL:
import { GlacierClient, DescribeJobCommand, GetJobOutputCommand } from "@aws-sdk/client-glacier"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; const client = new GlacierClient({ region: "你的AWS区域" }); const vaultName = "你的Glacier Vault名称"; export const handler = async (event) => { const jobId = event.queryStringParameters?.jobId; if (!jobId) { return { statusCode: 400, body: JSON.stringify({ error: "缺少任务ID(jobId)" }) }; } // 先查询任务状态 const describeParams = { vaultName: vaultName, jobId: jobId }; try { const describeCommand = new DescribeJobCommand(describeParams); const jobStatus = await client.send(describeCommand); if (jobStatus.Status !== "Succeeded") { return { statusCode: 202, body: JSON.stringify({ status: jobStatus.Status, message: "检索任务尚未完成,请稍后再试" }) }; } // 生成有效期1小时的预签名下载URL const getOutputParams = { vaultName: vaultName, jobId: jobId }; const command = new GetJobOutputCommand(getOutputParams); const downloadUrl = await getSignedUrl(client, command, { expiresIn: 3600 }); return { statusCode: 200, body: JSON.stringify({ downloadUrl: downloadUrl, archiveId: jobStatus.ArchiveId }) }; } catch (err) { return { statusCode: 500, body: JSON.stringify({ error: err.message }) }; } };
关键注意事项
- 检索类型选择:
Expedited(1-5分钟完成,成本最高)、Standard(3-5小时,平衡成本与速度)、Bulk(5-12小时,成本最低),根据业务需求调整。 - Lambda超时限制:检索任务耗时久,不能让发起任务的Lambda等待完成,必须拆分函数或用SNS/SQS触发后续流程。
- 预签名URL有效期:代码中设置为1小时,可通过
expiresIn参数调整(单位为秒)。
内容的提问来源于stack exchange,提问作者mayank3503
相关产品推荐
相关产品推荐

