Gunicorn、Django 和缓慢加载的代码...?

发布于 2024-10-21 01:57:43 字数 306 浏览 0 评论 0原文

我的代码使用 ma​​tplotlib ,它需要一两秒钟的时间来加载(看起来)。问题是,当我向 Gunicorn 发送 kill -HUP 时,对 Gunicorn 的下一个请求会在请求时加载实际代码,这需要一两秒的时间。

我不想强迫用户等待一两秒。我一直在尝试使用 urllib2.urlopen() 访问网站并强制某些实例加载代码,但我不能保证所有工作人员都已加载代码。

如何解决后端在请求时与启动时加载代码的问题?我是否将有问题的缓慢加载模块放入 settings.py 中?

My code uses matplotlib which takes a good second or two to load (it seems). The problem is that when I send kill -HUP <pid> to Gunicorn, that the next request to Gunicorn loads the actual code at request time which takes a good second or two.

I'd like to not force the user to wait that second or two. I've been playing around with hitting the website with urllib2.urlopen() and forcing some instances to load the code, but I cannot guarantee that all workers have loaded the code.

How can I work around the backend loading the code at request time vs when its started? Do I put the offending slow loading modules in settings.py?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴梦一场 2024-10-28 01:57:43

Gunicorn 有一些非常棒的配置。正在浏览其源代码的 git 克隆,发现了一个 example_config.py,其中有一个“post_fork”,这让我开始思考。经过一番研究后,我想出了这个解决方案。

% gunicorn_django -c path/to/gunicorn_conf.py path/to/settings.py

其中gunicorn_conf.py具有此功能:

def post_fork(server, worker):
    server.log.info("%s: Worker spawned" % worker.pid)

    from gunicorn.workers.sync import SyncWorker
    class SyncWorkerPreload(SyncWorker):
        def run(self):
            pass

        def init_process(self):
            super(SyncWorkerPreload, self).init_process()
            from django.db.models.loading import get_apps
            get_apps()
            server.log.info('%s: App loaded' % self.pid)
            super(SyncWorkerPreload, self).run()

    worker.__class__ = SyncWorkerPreload

希望可以帮助有人通过谷歌搜索找到此提示。

Gunicorn 足够灵活,可以做到这一点,真是太棒了!

更新:更新了代码,只是在设置中加载模块有时会因为我假设的 django 加载模块的方式而中断...这个新代码猴子修补了gunicorn以在“安全”时间加载模块...希望

更新:gunicorn 0.12.1 修复了这个问题

Gunicorn has some pretty awesome configuration. Was browsing around a git clone of their source and found an example_config.py which has a "post_fork" which got me thinking. After some poking around the source a bit more, I came up with this solution.

% gunicorn_django -c path/to/gunicorn_conf.py path/to/settings.py

Where gunicorn_conf.py has this function:

def post_fork(server, worker):
    server.log.info("%s: Worker spawned" % worker.pid)

    from gunicorn.workers.sync import SyncWorker
    class SyncWorkerPreload(SyncWorker):
        def run(self):
            pass

        def init_process(self):
            super(SyncWorkerPreload, self).init_process()
            from django.db.models.loading import get_apps
            get_apps()
            server.log.info('%s: App loaded' % self.pid)
            super(SyncWorkerPreload, self).run()

    worker.__class__ = SyncWorkerPreload

Hope that helps someone google'ing to find this hint.

Pretty awesome that Gunicorn was flexible enough to allow for this!

UPDATE: updated code, simply loading modules in settings sometimes breaks due to the way django loads modules I assume... this new code monkey patches gunicorn to load the modules at a "safe" time... hopefully

UPDATE: gunicorn 0.12.1 fixes this issue

方圜几里 2024-10-28 01:57:43

这听起来确实是由于 Django 对某些模块的延迟导入造成的。我要么使用settings.py,要么使用特定应用程序的urls.py,以便在工作程序启动时导入它们。

This does sound like it's due to Django's delayed imports on some modules. I'd either go with settings.py or maybe the specific app's urls.py to get them imported when the worker boots.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文