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

Uvicorn/FastAPI如何实现仅指定单个worker执行启动任务?

需求可以实现,以下是两种可行方案

Uvicorn多worker部署模式下,每个worker是独立的子进程,默认startup事件会在所有worker进程启动时各触发一次,你可以通过以下两种方式控制仅单个worker执行目标任务:

方案1:通过UVICORN_WORKER_ID环境变量判断(推荐,实现最简单)

Uvicorn 0.12.0及以上版本启动多worker时,会自动给每个worker进程注入UVICORN_WORKER_ID环境变量,取值从0开始按启动顺序递增,直接判断该值是否为0即可筛选出0号worker:

import os
import asyncio

@app.on_event('startup')
async def app_startup():
    worker_id = int(os.getenv("UVICORN_WORKER_ID", "0"))
    # 仅0号worker执行定时任务
    if worker_id == 0:
        asyncio.create_task(check_idle())
        asyncio.create_task(calculate_eta())

方案2:加锁机制(兼容所有Uvicorn版本,支持多机部署)

如果你的Uvicorn版本低于0.12.0,或是需要多机部署避免单点问题,可以用锁机制保证只有一个worker抢到执行权限:

  • 单机部署可以用文件锁:
import fcntl
import os
import asyncio

LOCK_FILE = "/tmp/worker_task.lock"

@app.on_event('startup')
async def app_startup():
    f = open(LOCK_FILE, "w")
    try:
        # 非阻塞抢锁,抢到的worker执行任务
        fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
        asyncio.create_task(check_idle())
        asyncio.create_task(calculate_eta())
    except BlockingIOError:
        # 没抢到锁直接跳过
        pass
  • 多机部署时把文件锁替换为Redis等分布式锁即可,逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 18:21:04