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

Firebase Functions 2代:如何在X分钟后丢弃重试事件?

Firebase Functions 1代转2代:事件时间戳获取与重试配置方案

一、获取事件时间戳(替代1代context.timestamp)

在2代Pub/Sub函数的event对象中,有两个符合RFC3339格式的时间戳可用,和1代格式完全兼容:

  • event.timestamp:事件触发的时间戳
  • event.data.message.publishTime:Pub/Sub消息本身的发布时间戳

你可根据需求选择,比如要判断消息从发布到处理的时长,用publishTime更准确;要判断事件触发到处理的时长,用event.timestamp即可。

修改适配2代的shouldDropEvent函数:

function shouldDropEvent(event, maxAgeMs = retryEventMaxAgeMs) {
  // 根据需求选择时间戳字段
  const eventTimestamp = event.data.message.publishTime;
  const eventAge = Date.now() - Date.parse(eventTimestamp);

  if (eventAge > maxAgeMs) {
    console.error(
      new Error(
        `Dropping event ${event.eventType} for ${event.resource.name} because max age was reached.`
      )
    );
    return true;
  }

  return false;
}

二、配置重试行为(替代1代failurePolicy)

2代函数的重试配置比1代更精细化,除基础开关外,还支持自定义重试次数、退避策略等参数:

  • 基础重试:设置retry: true即可开启,等效于1代的failurePolicy: true
  • 进阶配置:通过retryConfig设置具体规则,比如最大重试次数、最长重试时长、退避模式等

示例配置:

export const sendNotificationToUserToken_2ndGen = onMessagePublished(
  {
    topic: pubSendNotificationToUserToken.topic,
    // 基础重试开关
    retry: true,
    // 精细化重试规则(可选)
    retryConfig: {
      maxAttempts: 5, // 最大重试次数(含首次尝试)
      maxRetrySeconds: 1200, // 最长重试时长(20分钟,与你的retryEventMaxAgeMs对应)
      backoffMode: "EXPONENTIAL", // 退避模式:EXPONENTIAL(指数)/ LINEAR(线性)
      minBackoffSeconds: 60, // 最小退避间隔
      maxBackoffSeconds: 600, // 最大退避间隔
    },
  },
  async (event) => {
    // 加入事件过期判断逻辑
    if (shouldDropEvent(event, MINUTE_MS * 5)) {
      return;
    }
    await pubSendNotificationToUserToken.handle(event.data.message.json);
  }
);

完整修改后的代码

import { pubSendNotificationToUserToken } from "@repo/core/notifications";
import { onMessagePublished } from "firebase-functions/v2/pubsub";

const MINUTE_MS = 60 * 1000;
export const retryEventMaxAgeMs = 20 * MINUTE_MS;

export const sendNotificationToUserToken_2ndGen = onMessagePublished(
  {
    topic: pubSendNotificationToUserToken.topic,
    retry: true,
    retryConfig: {
      maxRetrySeconds: retryEventMaxAgeMs / 1000, // 转换为秒单位
      maxAttempts: 5,
      backoffMode: "EXPONENTIAL",
    },
  },
  async (event) => {
    if (shouldDropEvent(event, MINUTE_MS * 5)) {
      return;
    }
    await pubSendNotificationToUserToken.handle(event.data.message.json);
  }
);

/**
 * 判断事件是否超过最大存活时长
 */
function shouldDropEvent(event, maxAgeMs = retryEventMaxAgeMs) {
  const eventTimestamp = event.data.message.publishTime;
  const eventAge = Date.now() - Date.parse(eventTimestamp);

  if (eventAge > maxAgeMs) {
    console.error(
      new Error(
        `Dropping event ${event.eventType} for ${event.resource.name} because max age was reached.`
      )
    );
    return true;
  }

  return false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:34:57