mod_wsgi & django periodically hang in chromium
I've had this problem before, but have just deployed a new site to a completely different server and have the same problem. Using Chromium if I browse the site it'll occasionally just hang. Chromium has made a request to the server and just sits there waiting for a response. It stays like this for a minute or until I click on the stop button and try again. Sometimes it also hangs on the response - the spinner in chromium changes direction, the page goes white, but nothing else happens.
To make this happen I normally just have to visit several pages in quick succession. I normally see this after viewing approximately 10 pages. 'top' on the server shows nothing is happening (python/wsgi isn't executing), so it's not a problem of overloading the server. Nothing in the access log for the hit (i.e. it doesn't register), and nothing in the error log either.
I'm stumped. Please can someone point me in the direction of how I might go about debugging this. I can't release a site that performs the way this one currently does :-(
Thanks
Config files are as follows:
apache conf file:
<VirtualHost *:80>
ServerName mysite.org
ServerAlias www.mysite.* demo.mysite.org
# Rewrite rules to add 'www.' if it's not present
RewriteEngine On
RewriteCond %{HTTP_HOST} !(www|demo)\.mysite.org
RewriteRule ^(.*)$ http://www.mysite.org$1 [R=301,L]
WSGIDaemonProcess mycms processes=5 threads=5 display-name=%{GROUP} \
user=nobody group=nobody
WSGIScriptAlias / /var/www/python/mycms/mycms/conf/apache/mycms.wsgi \
process-group=mycms application-group=%{GLOBAL}
<Directory /var/www/python/mycms/mycms/conf/apache/>
WSGIProcessGroup mycms
Order deny,allow
Allow from all
</Directory>
Alias /media/admin/ /var/www/python/mycms/venv/lib/python2.7/site-packages/Django-1.2.5-py2.7.egg/django/contrib/admin/media/
<Directory /var/www/python/mycms/venv/lib/python2.7/site-packages/Django-1.2.5-py2.7.egg/django/contrib/admin/media>
Order deny,allow
Allow from all
Options +FollowSymLinks
</Directory>
Alias /media/ /var/www/python/mycms/mycms/media/
<Directory /var/www/python/mycms/mycms/media>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
wsgi:
import os
import sys
root = os.path.join(os.path.dirname(__file__), '../../..')
sys.path.insert(0, root)
activate_this = os.path.join(root, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
os.environ['PYTHON_EGG_CACHE'] = '/tmp/python-eggs'
os.environ['DJANGO_SETTINGS_MODULE'] = 'mycms.settings_production'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
(partial) settings.py:
import os
# Django settings for mycms project.
gettext = lambda s: s
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'mycms', # Or path to database file if using sqlite3.
'USER': 'user', # Not used with sqlite3.
'PASSWORD': 'pass', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
SITE_ID = 1
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = '/media/'
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/admin/'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.开发者_如何学PythonCsrfViewMiddleware',
'mycms.app.middleware.SiteDetectionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.multilingual.MultilingualURLMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.media.PlaceholderMediaMiddleware',
)
ROOT_URLCONF = 'mycms.urls'
TEMPLATE_DIRS = os.path.join(BASE_DIR, 'templates')
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.sitemaps',
'cms',
'cms.plugins.text',
'cms.plugins.picture',
'cms.plugins.link',
'cms.plugins.file',
'cms.plugins.teaser',
'cms.plugins.googlemap',
'appmedia',
'mptt',
'publisher',
'menus',
'cmsplugin_contact',
'mycms.app.html-sitemap',
'mycms.app.siteprofile',
'haystack',
'cms_search',
'cms_search.search_helpers',
)
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.i18n",
"django.core.context_processors.request",
"django.core.context_processors.media",
"mycms.app.context_processors.multisite",
"cms.context_processors.media",
)
SiteDetectionMiddleware (disabling this doesn't fix the problem though). I'm using this because I want to serve say 50 sites from a single django installation and have a pool of workers which can serve all sites. Having one wsgi per site would preallocate resources but wouldn't allow for any flexibility to reallocate them between sites when some are busier than others:
from django.contrib.sites.models import Site
from django.conf import settings
from django.http import HttpResponseServerError
from mycms.app.siteprofile.models import *
class SiteDetectionMiddleware:
"""
Sets the SITE_ID depending on the current HTTP host name.
This allows multiple sites with identical settings to be run
easily.
"""
def process_request(self, request):
host = request.META.get('HTTP_HOST')
if host:
try:
site = Site.objects.get(domain=host)
settings.SITE_ID = site.id
profile = Profile.objects.get(site=site)
settings.CMS_TEMPLATES = profile.get_template_tuples() + \
(settings.CMS_TEMPLATES[len(settings.CMS_TEMPLATES) - 1],)
except Site.DoesNotExist:
return HttpResponseServerError()
except Profile.DoesNotExist:
pass
Use:
http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Tracking_Request_and_Response
to determine if actually getting as far as mod_wsgi when hang happens. Debug from there.
精彩评论