Django如何实现类实例仅初始化一次供所有请求复用?
单实例复用解决方案
实现逻辑
Gunicorn采用多worker独立进程模式运行Django应用,我们只要保证每个worker进程内仅初始化一次自定义模块,就可以满足所有请求复用实例的需求,无需跨进程共享实例。
具体操作步骤
步骤1:通过Django AppConfig的ready()方法初始化实例
这是Django官方推荐的启动时执行自定义逻辑的方式,代码如下:
# 你的App目录下的apps.py from django.apps import AppConfig # 导入你自己写的自定义模块 from your_custom_package import YourLoadClass class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = "your_app_name" # 全局存储初始化后的实例 shared_module_instance = None def ready(self): # 避免重复初始化 if not self.shared_module_instance: # 此处执行耗时30秒的初始化、数据加载逻辑 self.shared_module_instance = YourLoadClass()
步骤2:业务代码直接复用初始化好的实例
在视图或其他业务逻辑中直接引用提前初始化好的实例即可,无需再次初始化:
# 你的业务视图代码 from your_app_name.apps import YourAppConfig def your_business_view(request): # 直接调用已初始化的实例,跳过30秒加载过程 result = YourAppConfig.shared_module_instance.run_business_logic(request.GET) return JsonResponse({"data": result})
步骤3:调整Gunicorn配置优化初始化次数
打开你的Gunicorn配置文件(通常是gunicorn.conf.py),添加如下配置:
# 开启预加载,主进程先初始化代码再fork worker,所有worker复用同一份初始化好的实例,全程仅初始化1次 preload_app = True
如果你的自定义模块不支持多进程共享(非进程安全),把preload_app改为False即可,此时每个worker进程启动时会单独初始化一次,总初始化次数等于你配置的worker数量,远低于每次请求都初始化的消耗。
注意事项
ready()方法内仅执行自定义模块的初始化、静态数据加载逻辑,不要写入数据库操作、请求处理相关代码- 本地调试使用
python manage.py runserver时如果开启了自动重载,ready()会执行2次,属于本地调试的正常现象,部署到Gunicorn后不会出现 - 如果自定义模块非线程安全,调用实例时加线程锁即可,示例如下:
import threading lock = threading.Lock() def your_business_view(request): with lock: result = YourAppConfig.shared_module_instance.run_business_logic(request.GET) return JsonResponse({"data": result})
内容的提问来源于stack exchange,提问作者Tri nguyen minh
相关产品推荐
相关产品推荐

