Supabase 自部署 Edge Functions 超时从 60s 延长到 360s 完整复盘

背景

在自部署 Supabase 环境中,Edge Functions 默认超时时间为 60 秒 。业务场景需要一个耗时较长的函数(约 350 秒),因此需要将超时延长至 360 秒

自部署 Supabase 的 Edge Functions 超时涉及多个层级,任何一层配置不正确都会导致请求被提前切断。本文记录了完整的排查过程和最终解决方案。

一、问题现象

创建一个测试函数 slow-test,等待 90 秒后返回:

javascript 复制代码
Deno.serve(async (req: Request) => {
  const startTime = Date.now();
  console.log("[slow-test] 函数开始执行,时间戳: " + startTime);
  await new Promise((resolve) => setTimeout(resolve, 90000));
  const duration = (Date.now() - startTime) / 1000;
  console.log("[slow-test] 等待结束,实际耗时: " + duration + " 秒");
  return new Response(JSON.stringify({ message: "成功执行了 " + duration + " 秒" }), {
    headers: { "Content-Type": "application/json" },
  });
});

现象:函数在约 60 秒时被强制终止,日志显示:

vbscript 复制代码
wall clock duration warning: isolate: xxx
wall clock duration reached: isolate: xxx (in_flight_req_exists = true)
failed to send request to user worker: request has been cancelled by supervisor
user worker failed to respond: request has been cancelled by supervisor

二、超时链路分析

Supabase Edge Functions 的请求链路涉及三个独立层级,每个层级都有自己的超时限制:

java 复制代码
客户端 → Kong 网关 → Edge Runtime (Worker) → 用户函数
         ↓              ↓
    read_timeout    workerTimeoutMs
层级 配置位置 默认值 作用
Kong 网关 kong.yml 中 functions-v1.read_timeout 150000ms (150s) 网关等待上游响应的时长
Edge Runtime 参数 docker-compose.yml 命令行参数 60s Worker 空闲超时
Edge Runtime 硬编码 main/index.ts 中 workerTimeoutMs 60s 最终生效的硬上限
环境变量 docker-compose.yml 环境变量 --- 辅助配置,可能被覆盖

关键原则 :main/index.ts 中的 workerTimeoutMs 是最终生效的硬编码值,优先级高于环境变量和命令行参数。

三、完整解决方案

3.1 修改 main/index.ts(核心)

这是最关键的一步,Edge Runtime 内部的硬编码超时值优先于所有环境变量和命令行参数。

找到 volumes/functions/main/index.ts,修改 workerTimeoutMs:

arduino 复制代码
// 修改前
const workerTimeoutMs = 60 * 1000; // 60秒


// 修改后
const workerTimeoutMs = 360 * 1000; // 360秒

3.2 修改 kong.yml

找到 volumes/api/kong.yml 中的 functions-v1 服务,修改超时配置:

yaml 复制代码
- name: functions-v1
  _comment: 'Edge Functions: /functions/v1/* -> http://functions:9000/*'
  url: http://functions:9000/
  read_timeout: 370000      # 从 150000 改为 370000(370秒)
  write_timeout: 370000     # 新增
  connect_timeout: 30000    # 新增
  routes:
    - name: functions-v1-all
      strip_path: true
      paths:
        - /functions/v1/
  plugins:
    - name: cors

注意 :Kong 的超时单位是毫秒。370000 表示 370 秒,比 Edge Runtime 的 360 秒多 10 秒缓冲,避免边界问题。

3.3 修改 docker-compose.yml

kong 服务 --- 环境变量:

yaml 复制代码
kong:
  environment:
    # ... 已有配置 ...
    KONG_NGINX_PROXY_PROXY_READ_TIMEOUT: "370s"
    KONG_NGINX_PROXY_PROXY_SEND_TIMEOUT: "370s"
    KONG_NGINX_PROXY_PROXY_CONNECT_TIMEOUT: "30s"

functions 服务 --- 环境变量与启动命令:

bash 复制代码
functions:
  environment:
    # ... 已有配置 ...
    FUNCTIONS_WORKER_TIMEOUT_MS: "360000"
    EDGE_RUNTIME_WORKER_TIMEOUT_MS: "360000"
  command:
    [
      "start",
      "--main-service",
      "/home/deno/functions/main",
      "--user-worker-request-idle-timeout",
      "360000",
      "--request-read-timeout",
      "360000",
      "--request-wait-timeout",
      "360000"
    ]

顶层 volumes --- 补充 deno-cache

yaml 复制代码
volumes:
  db-config:
  deno-cache:          # 确保这一行存在
  supabase_db_data:

四、配置层级总结

层级 配置文件 配置项
Kong 网关 kong.yml functions-v1.read_timeout 370000ms
Kong 网关(兜底) docker-compose.yml (kong) KONG_NGINX_PROXY_PROXY_READ_TIMEOUT 370s
Edge Runtime 参数 docker-compose.yml (functions) --user-worker-request-idle-timeout 360000ms
Edge Runtime 环境变量 docker-compose.yml (functions) FUNCTIONS_WORKER_TIMEOUT_MS 360000
Edge Runtime 硬编码 main/index.ts workerTimeoutMs 360 * 1000

必须形成的关系:Kong(370s) > Edge Runtime(360s) > 实际需求

五、验证测试

5.1 测试函数

javascript 复制代码
// volumes/functions/slow-test/index.ts
Deno.serve(async (req: Request) => {
  const startTime = Date.now();
  console.log("[slow-test] 函数开始执行,时间戳: " + startTime);


  const waitSeconds = 350; // 测试值
  console.log("[slow-test] 开始等待 " + waitSeconds + " 秒...");


  await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));


  const duration = (Date.now() - startTime) / 1000;
  console.log("[slow-test] 等待结束,实际耗时: " + duration + " 秒");


  return new Response(
    JSON.stringify({
      message: "成功执行了 " + duration + " 秒的操作",
      durationSeconds: duration,
    }),
    { status: 200, headers: { "Content-Type": "application/json" } }
  );
});

5.2 触发测试

bash 复制代码
ANON_KEY=$(grep ANON_KEY .env | cut -d '=' -f2)


curl -X POST "http://127.0.0.1:8000/functions/v1/slow-test" \
  -H "Authorization: Bearer ${ANON_KEY}" \
  -H "Content-Type: application/json"

5.3 成功日志

css 复制代码
[Info] [slow-test] 开始等待 350 秒...
[Info] [slow-test] 等待结束,实际耗时: 349.986 秒

5.4 验证命令

perl 复制代码
# 确认 Kong 环境变量
docker exec -it supabase-kong env | grep -iE "PROXY_READ|PROXY_SEND|PROXY_CONNECT"


# 确认 Edge Runtime 启动参数
docker inspect supabase-edge-functions --format '{{.Config.Cmd}}'


# 确认 main/index.ts 中的超时值
grep -n "workerTimeoutMs" ./volumes/functions/main/index.ts


# 确认 kong.yml 中的超时值
grep -n "read_timeout" ./volumes/api/kong.yml

六、踩坑记录

坑 1:只改环境变量不生效

原因:main/index.ts 中的 workerTimeoutMs 是硬编码值,优先级高于环境变量。

解决:必须修改 main/index.ts 中的 workerTimeoutMs。

坑 2:Kong 返回 The upstream server is timing out

原因 :kong.yml 中 functions-v1 服务的 read_timeout 是 150000(150秒),服务级配置优先级高于环境变量

解决:修改 kong.yml 中的 read_timeout 为 370000。

坑 3:开发环境配置不生效

原因 :开发环境使用了独立的 main/index.ts 文件,其 workerTimeoutMs 仍然是默认的 60 秒。

解决:每个环境都需要单独修改对应的 main/index.ts 文件。

坑 4:参数传递正确但仍不生效

原因:参数虽然被正确传递到容器(通过 docker inspect 确认),但 Edge Runtime 版本可能不识别这些参数。

解决:确认 Edge Runtime 版本兼容性,并确保 main/index.ts 中的硬编码值已修改。

七、注意事项

7.1 CPU 时间限制仍然存在

即使墙上时钟延长到 360 秒,CPU 执行时间限制仍然是 2 秒。纯 setTimeout 等待(I/O 密集型)不受影响,但计算密集型任务仍会在 2 秒左右被终止。

7.2 请求空闲超时

请求空闲超时(Request Idle Timeout)默认是 150 秒。如果函数在 150 秒内没有发出响应,平台仍会返回 504 错误。

7.3 最大支持 400 秒

自部署 Supabase 的 Edge Functions 墙上时钟上限最大可配置为 400 秒。如需延长到 400 秒,将所有相关值从 360000 改为 400000,Kong 的 read_timeout 改为 410000 即可。

7.4 重启方式

修改配置后必须完全停止并重建,不能用 restart:

bash 复制代码
docker compose down kong functions
docker compose up -d kong functions

八、总结

问题 解决方案
默认 60 秒超时 修改 main/index.ts 中的 workerTimeoutMs
Kong 150 秒切断 修改 kong.yml 中 functions-v1.read_timeout
环境变量不生效 硬编码值优先级最高,必须改代码
开发环境独立配置 每个环境单独修改 main/index.ts

核心结论 :Supabase Edge Functions 超时配置需要三层对齐,其中 main/index.ts 中的 workerTimeoutMs 是最终生效的硬编码值,是最关键的配置项。

相关推荐
当下新鲜事1 小时前
脱硫脱硝塔动力系统科普:四方DL500变频器工作原理解析
大数据·运维·物联网·业界资讯
Lsetea2 小时前
Nginx报No required SSL certificate was sent:mTLS客户端证书排查
运维·nginx·https·ssl·openssl
山岚的运维笔记2 小时前
mysql 专业笔记 -- 第 36 章:MySQL 管理
运维·数据库·笔记·后端·mysql·oracle·dba
DFT计算杂谈3 小时前
TRIQS 4.0.2 完整安装与使用指南
运维
蓝速科技4 小时前
商用复杂环境翻译机耐用性选型指南丨蓝速科技
大数据·运维·数据库·人工智能·科技
yt004yt4 小时前
工业园区绿岛 VOCs 废气治理管网设计与能碳节能设计经验分享
大数据·运维
starzy19904 小时前
Flink Sliding Window 详解及代码实现:从窗口重叠到状态爆炸防控
运维·数据库·flink
志栋智能6 小时前
集成是关键:让巡检超自动化融入现有工具链
运维·服务器·数据库·架构·自动化
AI智能从业者6 小时前
数码家电客服机器人怎么选?客户问参数问题机器人能不能接住
运维·人工智能·自动化