FlipperPA
FlipperPA

Reputation: 14311

mod_wsgi takes minutes on first page load after Apache restart

I have an outlier of a Django project with thousands of models. It serves as a RESTful API to data we have using Django REST Framework. When I start Django's runserver, it takes several minutes to come up, due to validating the data models in the project. Once loaded, it works as expected.

mod_wsgi exhibits a similar behavior. After a publish or when we restart Apache, the first time we bring up the page in a browser takes several minutes. After that first page load, the entire site is pretty much instantly responsive. From reading the documentation, this seems to be when mod_wsgi is loading the application into the GLOBAL application group. I've been trying to find a way to start this loading process immediately after a deployment (which touches wsgi.py), or an Apache restart, to avoid having to bring the website up in a browser after a deployment, which is problematic in production as we have several web servers behind a round-robin proxy, on a private network.

I have tried both adding the GLOBAL application group to the WSGIScriptAlias and adding WSGIImportScript, but neither seems to work.

Here is my .conf file for the VirtualHost in question. I'm clearly missing something.

<VirtualHost *:443>
  SSLEngine On

  ServerName django-project-dev.my.domain.com
  ErrorLog "|/usr/sbin/cronolog /path/to/log/httpd/errorlog/%Y/%Y-%m-django-project-dev-error.log"
  LogLevel info

  WSGIApplicationGroup %{GLOBAL}
  WSGIDaemonProcess django-project-dev-https python-home=/path/to/django/djangoproject/virtualenvs/django-project-dev request-timeout=1800 connect-timeout=300 socket-timeout=600 user=djangoproject group=wharton
  WSGIProcessGroup django-project-dev-https
  WSGIScriptAlias / /path/to/django/djangoproject/html/django-project-dev/config/wsgi.py process-group=django-project-dev-https application-group=%{GLOBAL}
  WSGIImportScript /path/to/django/djangoproject/html/django-project-dev/config/wsgi.py process-group=django-project-dev-https application-group=%{GLOBAL}

  <Directory /path/to/django/djangoproject/html/django-project-dev/config>
    Require all granted
  </Directory>

  Alias /static/ /path/to/django/djangoproject/html/django-project-dev/static/
  <Directory /path/to/django/djangoproject/html/django-project-dev/static>
    Require all granted
  </Directory>

  # This is required for Django REST Framework Auth Pass Thru
  WSGIPassAuthorization On
</VirtualHost>

Upvotes: 1

Views: 680

Answers (1)

Graham Dumpleton
Graham Dumpleton

Reputation: 58523

For preloading, instead of:

  WSGIApplicationGroup %{GLOBAL}
  WSGIDaemonProcess django-project-dev-https python-home=/path/to/django/djangoproject/virtualenvs/django-project-dev request-timeout=1800 connect-timeout=300 socket-timeout=600 user=djangoproject group=wharton
  WSGIProcessGroup django-project-dev-https
  WSGIScriptAlias / /path/to/django/djangoproject/html/django-project-dev/config/wsgi.py process-group=django-project-dev-https application-group=%{GLOBAL}
  WSGIImportScript /path/to/django/djangoproject/html/django-project-dev/config/wsgi.py process-group=django-project-dev-https application-group=%{GLOBAL}

Use just:

  WSGIDaemonProcess django-project-dev-https python-home=/path/to/django/djangoproject/virtualenvs/django-project-dev request-timeout=1800 connect-timeout=300 socket-timeout=600 user=djangoproject group=wharton
  WSGIScriptAlias / /path/to/django/djangoproject/html/django-project-dev/config/wsgi.py process-group=django-project-dev-https application-group=%{GLOBAL}

The use of both process-group and application-group on WSGIScriptAlias is enough to trigger preloading of the WSGI script file. The WSGIImportScript did the same, but you don't need it if you use both options on WSGIScriptAlias. Having used those options on WSGIScriptAlias, you also don't need WSGIProcessGroup or WSGIApplicationGroup.

Do make sure though that you also add:

WSGIRestrictedEmbedded On

outside of the VirtualHost so you aren't setting up Python inside of all Apache worker processes as well. You only need it in the mod_wsgi daemon processes.

Try that and see where you get to.

As you have:

LogLevel info

in Apache configuration that should cause mod_wsgi to log more about what it is doing and when it is loading things so you can verify what is happening.

Upvotes: 3

Related Questions