You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.JS检查S3存储桶近X天是否有指定文件上传

问题1:Node.js实现S3指定文件上传状态校验的实现方式

直接用AWS SDK for JavaScript v3实现即可,核心逻辑是拉取S3单个文件的元数据做时间比对,不要用遍历桶的接口查单个文件,效率极低还容易出问题。

首先安装依赖:
npm install @aws-sdk/client-s3 @aws-sdk/client-lambda

核心校验逻辑代码如下,可以直接放到Lambda或者Node.js服务中运行:

const { S3Client, HeadObjectCommand } = require("@aws-sdk/client-s3");
const { LambdaClient, InvokeCommand } = require("@aws-sdk/client-lambda");

// 初始化客户端,替换为你的资源所在AWS区域,比如ap-southeast-1
const s3Client = new S3Client({ region: "your-aws-region" });
const lambdaClient = new LambdaClient({ region: "your-aws-region" });

/**
 * 校验指定S3文件90天内是否有上传,无上传则触发缓存加载Lambda
 * @param {string} bucketName S3桶名
 * @param {string} fileKey 待校验文件的完整路径key
 * @param {string} lambdaFunctionName 缓存加载Lambda的函数名
 */
async function checkFileAndTriggerCache(bucketName, fileKey, lambdaFunctionName) {
  const ninetyDaysTimestamp = Date.now() - 90 * 24 * 60 * 60 * 1000;
  let needTrigger = false;

  try {
    // 直接拉取文件元数据,不用下载文件,性能最高
    const fileMeta = await s3Client.send(new HeadObjectCommand({
      Bucket: bucketName,
      Key: fileKey
    }));
    // 比对最后修改时间,早于90天前则需要触发
    if (fileMeta.LastModified.getTime() < ninetyDaysTimestamp) {
      needTrigger = true;
    }
  } catch (err) {
    // 文件不存在直接判定需要触发
    if (err.name === "NotFound") {
      needTrigger = true;
    } else {
      // 权限错误、网络错误等直接抛出,避免误触发
      throw err;
    }
  }

  if (needTrigger) {
    // 异步触发Lambda,不用等待执行结果
    await lambdaClient.send(new InvokeCommand({
      FunctionName: lambdaFunctionName,
      Payload: Buffer.from(JSON.stringify({
        source: "s3-90day-check",
        bucket: bucketName,
        key: fileKey
      })),
      InvocationType: "Event"
    }));
    return { status: "lambda_triggered", msg: "file not uploaded in 90 days, cache reload started" };
  }

  return { status: "skip", msg: "file uploaded within 90 days, cache is valid" };
}

注意:不要用listObjectsV2接口遍历桶查找指定文件,这个接口是用来批量列对象的,查单个文件纯属浪费请求额度,文件量大的时候还要处理分页逻辑,容易出bug。HeadObject是查询单个文件元数据的官方标准接口,一次请求就能拿到结果,成本最低。

落地时需要注意权限配置:

  • 跑这段代码的身份(IAM角色/用户)只需要配两个最小权限:目标存储桶的s3:HeadObject权限,目标缓存加载Lambda的lambda:InvokeFunction权限,不要给多余权限。
  • 触发Lambda时固定用InvocationType: 'Event'走异步触发,不用等Lambda执行完返回,避免校验逻辑超时。

问题2:Cron Job巡检的可行性与更优方案

首先给结论:自托管Cron Job巡检是可行的,但不是最优解,存在明显短板。

自托管Cron的问题

  • 有单点故障风险:跑Cron的服务器挂了就会漏校验,要自己做高可用,运维成本高。
  • 凭证管理麻烦:要自己维护AK/SK,定期轮换,漏换就会导致校验逻辑失效。
  • 精度和成本难平衡:巡检间隔设短了,会产生大量无效的S3 API请求,增加成本;设长了,文件过了90天窗口期后要等很久才会被加载到缓存,影响业务。

托管式定时巡检方案(适合文件量小的场景)

如果要走定时巡检的路线,别自己搭Cron,直接用EventBridge Scheduler(原CloudWatch Events)定时触发一个跑上述校验逻辑的Lambda即可,是Cron方案的托管升级版:

  • 不用管服务器运维,AWS本身保障服务可用性,调度精度最高到1分钟。
  • 自带重试、死信队列能力,不会因为单次请求失败漏校验。
  • Lambda直接绑定IAM角色就行,不用自己管凭证轮换。

如果待校验文件只有几十到几百个,每天触发一次巡检完全够用,实现成本极低。

更优的事件驱动+精准调度方案(适合文件量大的场景)

如果待校验文件量级大(上千甚至更多),定时全量巡检的成本会很高,推荐用下面的方案,几乎没有无效请求,精度也最高:

  • 保留现有的S3上传事件直接触发Lambda写缓存的流程,这部分是实时的,上传完成立刻同步缓存,无延迟。
  • 每次上传事件触发Lambda写缓存时,同步在EventBridge Scheduler里创建一个90天后触发的一次性调度任务,任务内容就是跑上述的单文件校验逻辑:到点后检查这个文件的最后上传时间,如果确实90天内没有新上传,就主动触发加载缓存的Lambda,再创建下一个90天的一次性调度;如果90天内已经有新上传触发过缓存同步,直接删掉这个过期的调度任务就行。
  • 额外给缓存条目加90天TTL做兜底,极端情况调度任务丢了,缓存过期时也会触发回源加载,不会出现缓存空窗。

这个方案没有全量巡检的空跑开销,每个文件只会在刚好到90天窗口期的时候做一次校验,比定时全量扫省90%以上的API成本,也不会有巡检间隔带来的同步延迟。


内容的提问来源于stack exchange,提问作者Aravind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:03:25