【问题标题】:Models.py not getting loaded on startup with uWSGI使用 uWSGI 启动时未加载 Models.py
【发布时间】:2012-06-21 18:42:31
【问题描述】:

我有一个系统,我需要在请求之前和之后对 URL 进行完全动态控制。

我为此使用信号,并且对于预请求信号(我遇到问题的那个,我有一个像这样的中间件,它连接到信号,允许它检查当前请求.path 适用于它,然后与它获得的第一个一起使用。这通常工作正常,并且相当优雅):

class PreRouteMiddleWare(object):
    def process_request(self, request):
        url = request.path.strip('/')
        if url == '':
            url = '/'
        pre_routes = pre_route.send(sender=request, url=url)
        for reciever, response in pre_routes:
            if response:
                return response
        return None

现在,要注册在 Django 路由堆栈“之前”发生的事情,我在应用程序的 models.py 中执行类似的操作:

@receiver(pre_route)
def try_things(sender, url, **kwargs):
    try:
        thing= Thing.objects.get(url=url)
        from myapp.views import myview
        return myview(sender, some_args)
    except Thing.DoesNotExist:
        return False

这在我的开发服务器上也很有效。

但是,问题出现在我使用 uWSGI 的生产环境中。我像这样启动 uWSGI(从新贵):

sudo /usr/local/bin/uwsgi --emperor '/srv/*/uwsgi.ini' --enable-threads --single-interpreter

我的 uwsgi.ini 看起来像这样:

[uwsgi]
socket = /srv/new/uwsgi.sock
module = wsgi:app
chdir = /srv/new/myapp
virtualenv = /srv/new
env = DJANGO_SETTINGS_MODULE=myapp.settings
uid = wsgi_new
gid = www-data
chmod = 770
processes = 2

似乎正在发生的事情是对于每个 uWSGI 进程/线程,它们似乎只在第一个请求时加载 models.py,这意味着每个进程的第一个请求将无法连接信号。这意味着我有 n 个(其中 n 是进程数)请求完全失败,因为 models.py 在启动时没有加载(因为它正在开发中)。

我是否配置了 uWSGI 错误?有没有更好的方法来强制在启动时连接信号?

【问题讨论】:

    标签: django wsgi uwsgi django-signals django-wsgi


    【解决方案1】:

    Django 实际上是懒惰地加载东西。使用开发服务器会让人产生一种错误的安全感,即事情将如何在真正的 WSGI 服务器中工作,因为开发服务器加载管理命令会强制进行大量早期初始化,而生产服务器不会发生这种情况。

    你可能会读到:

    http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

    它解释了在 mod_wsgi 中出现的问题。 uWSGI 也会发生同样的事情。

    【讨论】:

      【解决方案2】:

      好的,事实证明我需要让我的中间件挂钩 process_view 而不是 process_request:

      class PreRouteMiddleWare(object):
          def process_view(self, request, *args, **kwargs):
              url = request.path.strip('/')
              if url == '':
                  url = '/'
              pre_routes = pre_route.send(sender=request, url=url)
              for reciever, response in pre_routes:
                  if response:
                      return response
              return None
      

      现在效果很好!

      【讨论】:

        猜你喜欢
        • 2020-09-12
        • 2013-05-09
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 2016-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多