Server Action间歇性执行失败问题

profile image

Vercel无服务器环境中Server Action回调间歇性执行失败的原因分析与解决方案。

本帖由 Jetbrains's Coding Agent Junie junie logo翻译。如有任何翻译错误,请告知我们!

问题

在服务器端执行以下Mixpanel跟踪代码时,事件仅间歇性地被记录。

typescript
mixpanel.track(event, { distinct_id: userId, properties }, err => {
  if (err) {
    reject(err);
  } else {
    resolve("success");
  }
});

在本地环境中,所有事件都能正常记录,但在Vercel部署环境中,只有部分事件被记录的问题。

原因

在查看原因之前,让我们了解一下Vercel Functions。Vercel为部署到Vercel的环境提供了一个称为Vercel Functions的功能。

简单地解释Vercel Functions,在Vercel部署环境中的所有服务器端代码执行都在Vercel的基础设施环境下运行。也就是说,应用了FaaS(Function as a Service)。

什么是FaaS?

FaaS是Function as a Service的缩写,是实现无服务器计算的一种方式。这里的Function指的就是我们在开发中使用的那个Function,这个概念是将这些函数上传到云服务,只在需要时调用。
换句话说,FaaS允许你无需开发服务器就能执行函数。
正是由于Vercel的这一功能,我们无需特别进行服务器设置就能使用API Routes或SSR等功能。

Note

Vercel的无服务器架构通过AWS Lambda运行。

出现问题的代码也被设置为**服务器操作(Server Action)**并在服务器上执行,由于Vercel基于无服务器运行,代码被注册为无服务器函数。

然而,无服务器函数在执行过程中可能会终止进程,在这种情况下,函数可能在异步任务完成前就终止了。也就是说,callback函数没有被执行,所以事件没有被正确传输。

解决方案

因此,我们将代码用Promise包装,如下所示,所有事件都能正常记录了。

typescript
return new Promise((resolve, reject) => {
    mixpanel.track(event, { distinct_id: userId, properties }, (err) => {
      if (err) {
        reject(err)
      } else {
        resolve('success')
      }
    })
  })

为什么在服务器端执行跟踪代码

那么,为什么不在客户端执行像mixpanel.track这样的跟踪代码呢?

  • 数据完整性:当从客户端直接发送事件时,由于用户的浏览器设置(例如:广告拦截器)或网络问题,事件可能会丢失。在服务器端执行可以减少这些外部因素,实现更可靠的数据收集。
  • 与业务逻辑集成:当跟踪事件与服务器端逻辑(例如:支付处理、用户认证等)密切相关时,在服务器上直接处理更自然、更高效。例如,要在支付完成后记录事件,在服务器上确认支付成功后再跟踪是合适的。
  • 性能优化:在客户端处理跟踪请求会导致额外的网络调用,增加页面加载时间。在服务器端处理可以减轻客户端负担,改善用户体验。

由于这些原因,如果可能的话,在服务器端而不是客户端执行可以获得更准确、更稳定的指标。


参考

❤️ 0
🔥 0
😎 0
⭐️ 0
🆒 0