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

使用多gunicorn worker时如何确保部分代码仅在单个进程中运行

多实例产生的原因

Gunicorn默认采用prefork进程模型:主进程启动时会先加载入口文件的全部代码,再fork出指定数量的worker子进程,每个子进程会完整复制父进程的内存空间,也会重新执行一次初始化逻辑,因此每个worker都会生成独立的VEngine实例,不同进程的实例完全隔离,无法共享状态。普通的线程级单例模式在这种多进程场景下完全失效。

注意:不要尝试用Gunicorn的--preload参数解决该问题,该参数仅能让主进程完成初始化后再fork子进程,多进程操作共享的IO资源(文件句柄、磁盘文件等)时会出现脏写、句柄泄漏等不可预知的问题,无法满足进程安全要求。

解决方案

下面是几种不同复杂度的实现方案,可根据业务场景选择:

方案1:单worker + 异步模型(改造成本最低)

如果业务属于IO密集型、请求量级不大,可以放弃多进程worker,改用单进程+异步协程的方式提高并发处理能力,天然保证只有一个VEngine实例。
操作步骤:

  1. 安装异步worker依赖:pip install gevent
  2. 修改启动命令,将worker数设为1,指定异步worker类型:
gunicorn -w 1 -k gevent entrypoint:app -b 0.0.0.0:8000

适用场景:中小流量的内部系统,无需大幅修改现有业务代码。

方案2:独立Engine daemon进程(稳定性最优)

将磁盘IO操作和Web服务完全解耦,单独启动一个常驻后台的daemon进程运行唯一的VEngine实例,所有gunicorn worker收到请求后,通过IPC(进程间通信)将读写请求转发给daemon处理,拿到结果后再响应客户端。
常用的IPC实现方式:

  • 轻量场景用Unix域套接字/Redis消息队列
  • 复杂场景用gRPC/ZeroMQ等RPC框架
    适用场景:生产环境大流量场景,避免多进程IO冲突,同时Web服务和IO服务可以独立扩容、故障隔离。

方案3:进程互斥锁(临时过渡方案)

如果暂时不想重构架构,可以用跨进程的互斥锁保证同一时间只有一个进程能执行IO操作,避免并发读写冲突:

  1. Linux环境下可用fcntl实现文件锁,也可以用multiprocessing模块的共享锁
  2. 所有调用get_data/put_data的位置先抢锁,抢到后再执行操作,执行完释放锁
    注意:该方案只是实现了IO操作的互斥访问,还是会初始化多个VEngine实例,锁竞争会导致性能下降,极端情况可能出现死锁,仅适合临时过渡使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:45:03