uwsgi cannot process request longer than one minute - django
I have a Django application that is served within docker container via uwsgi. I have prepared a custom view just to reproduce the issue I'm mentioning. It looks exactly like below:
def get(self, request):
logger = logging.getLogger('ReleaseReport')
logger.critical('Entering and sleeping')
time.sleep(180)
logger.critical('Awaking')
return Response({'response': 'anything'})
The only thing it does (intentionally) is to log message, sleep for 3 minutes, and log another message afterwards.
Here is how the log file works after I try to visit the view from Firefox / Chrome / PyCharm's rest API client:
spawned uWSGI worker 9 (pid: 14, cores: 1)
spawned uWSGI worker 10 (pid: 15, cores: 1)
spawned uWSGI http 1 (pid: 16)
CRITICAL 2018-08-31 12:10:37,658 views Entering and sleeping
CRITICAL 2018-08-31 12:11:37,742 views Entering and sleeping
CRITICAL 2018-08-31 12:11:38,687 views Awaking
[pid: 10|app: 0|req: 1/1] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:10:37 2018] GET /api/version/ => generated 5156 bytes in 61229 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)
CRITICAL 2018-08-31 12:12:37,752 views Entering and sleeping
CRITICAL 2018-08-31 12:12:38,784 views Awaking
[pid: 15|app: 0|req: 1/2] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:11:37 2018] GET /api/version/ => generated 5156 bytes in 61182 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)
CRITICAL 2018-08-31 12:13:38,020 views Entering and sleeping
CRITICAL 2018-08-31 12:13:38,776 views Awaking
[pid: 10|app: 0|req: 2/3] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:12:37 2018] GET /api/version/ => generated 5156 bytes in 61034 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)
After one minute, the view seems to be executed again, and after another minute the third time is executed. Moreover, the log says it is HTTP 200, but the client doesn't receive the data and just says it cannot load it after few more minutes (depends on client). However the first HTTP 200 in log occurs much earlier before client gives up.
Any clues what may be causing that issue? Here is my uwsgi.ini:
[uwsgi]
http = 0.0.0.0:8000
chdir = /app
module = web_server.wsgi:application
pythonpath = /app
static-map = /static=/app/static
master = true
processes = 10
vacuum = true
The Dockerfile command is as following:
/usr/local/bin/uwsgi --ini /app/uwsgi.ini
In my real application, it causes that client thinks the request failed, but since it was actually executed and finished 3 times, there are 3 records in a database. Changing worker processes number to 1 doesn't change much. Instead of waitin one minute to spawn view again, it is spawned after previous one finishes.
What's wrong with my configuration?
EDIT:
I have changed my view a bit, it now accepts sleep time parameter and looks like this:
def get(self, request, minutes=None):
minutes = int(minutes)
original_minutes = minutes
logger = logging.getLogger(__name__)
while minutes > 0:
logger.critical(f'Sleeping, {minutes} more minutes...')
time.sleep(60)
minutes -= 1
logger.critical(f'Slept for {original_minutes} minutes...')
return Response({'slept_for': original_minutes})
Now, curling:
> curl http://test-host/api/test/0
{"slept_for":0}
> curl http://test-host/api/test/1
{"slept_for":1}
> curl http://test-host/api/test/2
curl: (52) Empty reply from server
In log:
CRITICAL 2018-08-31 14:23:36,200 views Slept for 0 minutes...
[pid: 10|app: 0|req: 1/14] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:35 2018] GET /api/test/0 => generated 15 bytes in 265 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:23:42,878 views Slept for 0 minutes...
[pid: 10|app: 0|req: 2/15] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:42 2018] GET /api/test/0 => generated 15 bytes in 1 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:23:46,370 views Sleeping, 1 more minutes...
CRITICAL 2018-08-31 14:24:46,380 views Slept for 1 minutes...
[pid: 10|app: 0|req: 3/16] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:46 2018] GET /api/test/1 => generated 15 bytes in 60011 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:27:06,903 views Sleeping, 2 more minutes...
CRITICAL 2018-08-31 14:28:06,963 views Sleeping, 1 more minutes...
CRITICAL 2018-08-31 14:29:06,995 views Slept for 2 minutes...
[pid: 9|app: 0|req: 1/17] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:27:06 2018] GET /api/test/2 => generated 15 bytes in 120225 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
If I use the same command to test server running with manage.py runserver, it does answer every time - no matter if I sleep 2 minutes or 10. So it is not the client fault.
I've changed harakiri to 3600, no change.
EDIT2 (my Dockerfile):
FROM python:3.7.0-alpine
ADD . /app
RUN set -ex \
&& apk add mysql-dev \
pcre-dev \
&& apk add --no-cache --virtual .build-deps \
gcc \
make \
libc-dev \
musl-dev \
linux-headers \
libffi-dev \
&& pip install --no-cache-dir -r /app/requirements.txt \
&& runDeps="$( \
scanelf --needed --nobanner --recursive /venv \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --virtual .python-rundeps $runDeps \
&& apk del .build-deps
WORKDIR /app
RUN mkdir -p static
RUN python manage.py collectstatic --clear --noinput
EXPOSE 8000
CMD ["/usr/local/bin/uwsgi", "--ini", "/app/uwsgi.ini"]
It actually was the Dockerfile issue. Previously I had uWSGI in my requirements.txt, so it was installed by pip install.
When I've removed it and added uwsgi-python3 to apk add, now everything is fine.
No idea why it matters (everything else was working fine), but it solved my issue.
Related
'no python application found' in Django
I tried to deploy my Django project on server with uwsgi. I can initial uwsgi with uwsgi --ini conf/uwsgi.ini But when I tried to visit the website, I got this error --- no python application found, check your startup logs for errors --- [pid: 11228|app: -1|req: -1/1] 127.0.0.1 () {46 vars in 946 bytes} [Mon Nov 28 17:06:37 2022] GET / => generated 21 bytes in 0 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0) I put my repo at https://github.com/dolphinfafa/MyLife Anyone knows how to resolve this?
Add Username and Client IP Address in the Django manage.py runserver default output
Could anybody please help me, how to add Username and Clinet IP Address in the Django manage.py runserver default output. currently I am seeing: [01/Jul/2019 11:34:27] "GET / HTTP/1.1" 200 237 expected result: [pid: 10|app: 0|req: 1/2] 10.176.123.254 (Logged in username/email) {86 vars in 4942 bytes} [Mon Jul 1 06:08:37 2019] GET / => generated 291 bytes in 1160 msecs (HTTP/1.1 200) 7 headers in 250 bytes (1 switches on core 0)
How to disable request logging in Django and uWSGI?
My uWSGI logs are full of entries like this for every request: localhost [pid: 4029|app: 0|req: 1/1] 127.0.0.1 () {48 vars in 906 bytes} [Wed Mar 23 18:35:38 2016] GET / => generated 94847 bytes in 1137 msecs (HTTP/1.1 200) 4 headers in 224 bytes (1 switches on core 0) I'm not sure if it's uWSGI spamming them or Django. How can I disable the request logging?
What does your uwsgi.ini look like? That's where you'd want to disable logging. Set: disable-logging=True Here's the docs: http://uwsgi-docs.readthedocs.org/en/latest/Options.html#disable-logging
Or from the console with: uwsgi --disable-logging
project wsgi not found when started automatically but not manually
I do not understand why I get an error about not finding my "project.wsgi" module when supervisor tries to start the app automatically (for example when the server is starting.) 2014-02-15 05:13:05 [1011] [INFO] Using worker: sync 2014-02-15 05:13:05 [1016] [INFO] Booting worker with pid: 1016 2014-02-15 05:13:05 [1016] [ERROR] Exception in worker process: Traceback (most recent call last): File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker worker.init_process() File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process self.wsgi = self.app.wsgi() File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi self.callable = self.load() File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load return self.load_wsgiapp() File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp return util.import_app(self.app_uri) File "/var/local/sites/myproject/venv/local/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app __import__(module) ImportError: No module named myproject.wsgi Whereas I do not get this error and it works fine when I manually do: sudo supervisorctl start myapp What is different? Thanks UPDATE: supervisor conf file: [program:myproject] command=/var/local/sites/myproject/run/gunicorn_start ; Command to start app user=myproject ; User to run as autostart=true autorestart=true loglevel=info redirect_stderr=false stdout_logfile=/var/local/sites/myproject/logs/supervisor-myproject-stdout.log stdout_logfile_maxbytes=1MB stdout_logfile_backups=10 stdout_capture_maxbytes=1MB stderr_logfile=/var/local/sites/myproject/logs/supervisor-myproject-stderr.log stderr_logfile_maxbytes=1MB stderr_logfile_backups=10 stderr_capture_maxbytes=1MB /var/local/sites/myproject/run/gunicorn_start: #!/bin/bash NAME="myproject_app" # Name of the application USER=myproject # the user to run as GROUP=myproject # the group to run as NUM_WORKERS=3 # how many worker processes should Gunicorn spawn # Logs config LOG_LEVEL=info ACCESS_LOGFILE=/var/local/sites/myproject/logs/gunicorn-myproject-access.log ERROR_LOGFILE=/var/local/sites/myproject/logs/gunicorn-myproject-error.log echo "Starting $NAME" exec envdir /var/local/sites/myproject/env_vars /var/local/sites/myproject/venv/bin/gunicorn myproject.wsgi:application \ --name $NAME \ --workers $NUM_WORKERS \ --user=$USER --group=$GROUP \ --log-level=$LOG_LEVEL \ --bind=unix:/tmp/myproject.gunicorn.sock \ --access-logfile=$ACCESS_LOGFILE \ --error-logfile=$ERROR_LOGFILE
I think you should add directory to your supervisor configuration file. This is my template. I use this in every project and works fine: [program:PROJECT_NAME] command=/opt/sites/PROJECT_NAME/env/bin/gunicorn -c /opt/sites/etc/gunicorn/GUNICORN_CONF.conf.py PROJECT_NAME.wsgi:application directory=/opt/sites/PROJECT_NAME environment=PATH="/opt/sites/PROJECT/env/bin" autostart=true autorestart=false redirect_stderr=True stdout_logfile=/tmp/PROJECT_NAME.stdout
I have the same problem before. I'm using the following line in my gunicorn_start instead of envdir. I'm running a django application within a virtual env located in /env/nafd/ and my django app is located in /env/nafd/nafd_proj .. DJANGODIR=/to/path/app_proj cd $DJANGODIR source ../bin/activate` exec ../bin/gunicorn nafd_proj.wsgi:application \ --name $NAME \ --workers $NUM_WORKERS \ --user=$USER --group=$GROUP \ --log-level=$LOG_LEVEL \ --bind=unix:/tmp/myproject.gunicorn.sock \ --access-logfile=$ACCESS_LOGFILE \ --error-logfile=$ERROR_LOGFILE`
It's obvious, but it is worth to mention: check if "supervisord" daemon is running (service supervisor status). Here is the following setup that I have here, using a Flask app with WSGI (Gunicorn), controlled via Supervisor, and it is working perfectly. Flask App root#ilg40:~# ll /etc/tdm/flask/ total 1120 drwx------ 5 root root 4096 Jan 24 19:47 ./ drwx------ 3 root root 4096 Jan 23 00:20 ../ -r-------- 1 root root 1150 Aug 31 17:54 favicon.ico drw------- 2 root root 4096 Jan 13 22:51 static/ -rw------- 1 root root 883381 Jan 23 20:09 tdm.log -rwx------ 1 root root 73577 Jan 23 21:37 tdm.py* -rw------- 1 root root 56445 Jan 23 21:37 tdm.pyc drw------- 2 root root 4096 Jan 23 20:08 templates/ -rw-r--r-- 1 root root 493 Jan 23 22:42 wsgi.py -rw-r--r-- 1 root root 720 Jan 23 22:42 wsgi.pyc srwxrwxrwx 1 root root 0 Jan 24 19:47 wsgi.sock= Supervisor Config File root#ilg40:~# cat /etc/supervisor/conf.d/wsgi_flask.conf [program:wsgi_flask] command = gunicorn --preload --bind unix:/etc/tdm/flask/wsgi.sock --workers 4 --pythonpath /etc/tdm/flask wsgi process_name = wsgi_flask autostart = true autorestart = true stdout_logfile = /var/log/wsgi_flask/wsgi_flask.out.log stderr_logfile = /var/log/wsgi_flask/wsgi_flask.err.log Update Supervisord About The New Process root#ilg40:~# supervisorctl update wsgi_flask: added process group Checking Process Status root#ilg40:~# supervisorctl status wsgi_flask wsgi_flask RUNNING pid 1129, uptime 0:29:12 Note: in the setup above, I'm not using virtualenv, which I believe that could require the configuration of directory variable for the process and also, to configure environment PATH for the command variable (adding env PATH="$PATH:/the/app/path" gunicorn...), since that gunicorn, flask, and so on, are only located inside of the virtualenv.
Django app works via manage.py runserver but page rendered via mod_uwsgi fails to refer to static elements
I am at the end of my rope here... and plan to start digging into Django source code to figure this out. I have a Django app that has been created in the standard fashion via start project. So far I have been testing it via "python manage.py runserver 8081". Now I am trying to put this behind Nginx using mod_uwsgi. So I test it using the excellent instructions over here. My ini file looks as follows: uwsgi] chdir=<path_to_my_project> module=<application>.wsgi:application pidfile=/tmp/<pid_file_name> max-requests=5000 daemonize=/var/log/uwsgi/<log_file_name> env=DJANGO_SETTINGS_MODULE=<application>.settings http-socket=127.0.0.1:50000 So I start the app using: uwsgi --ini uwsgi.ini All seems to look good: Log file at "/var/log/uwsgi/" created: Looks good. Directory is changed: Looks good. Log file indicates so. Module is loaded: Assume that it has... I don't see any error message in the logs. pidfile is created: Looks good. I do see the correct PID number in the file. Tested the closing of the process via SIGINT. Listening at http-socket: Looks good. PROBLEM: When I hit the site via http://site_url; I get the HTML page in my browser. But none of the CSS styles are reflected. Also, none of my java-script functions are executed. So not sure what is amiss. FYI: I noticed the following lines in the log: [pid: 15730|app: 0|req: 7/7] 127.0.0.1 () {36 vars in 696 bytes} [Thu Apr 25 16:40:50 2013] GET / => generated 11774 bytes in 2 msecs (HTTP/1.1 200) 1 headers in 59 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 8/8] 127.0.0.1 () {36 vars in 710 bytes} [Thu Apr 25 16:40:50 2013] GET /static/jquery/jquery-1.9.1.min.js => generated 2874 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 9/9] 127.0.0.1 () {36 vars in 727 bytes} [Thu Apr 25 16:40:50 2013] GET /static/bootstrap/css/bootstrap.css => generated 2877 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 10/10] 127.0.0.1 () {36 vars in 716 bytes} [Thu Apr 25 16:40:50 2013] GET /static/bootstrap/js/bootstrap.min.js => generated 2883 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 11/11] 127.0.0.1 () {32 vars in 570 bytes} [Thu Apr 25 16:40:50 2013] GET /favicon.ico => generated 2808 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 12/12] 127.0.0.1 () {36 vars in 696 bytes} [Thu Apr 25 16:40:51 2013] GET / => generated 11774 bytes in 2 msecs (HTTP/1.1 200) 1 headers in 59 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 13/13] 127.0.0.1 () {36 vars in 710 bytes} [Thu Apr 25 16:40:51 2013] GET /static/jquery/jquery-1.9.1.min.js => generated 2874 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 14/14] 127.0.0.1 () {36 vars in 727 bytes} [Thu Apr 25 16:40:51 2013] GET /static/bootstrap/css/bootstrap.css => generated 2877 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 15/15] 127.0.0.1 () {36 vars in 716 bytes} [Thu Apr 25 16:40:51 2013] GET /static/bootstrap/js/bootstrap.min.js => generated 2883 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) [pid: 15730|app: 0|req: 16/16] 127.0.0.1 () {32 vars in 570 bytes} [Thu Apr 25 16:40:51 2013] GET /favicon.ico => generated 2808 bytes in 3 msecs (HTTP/1.1 404) 1 headers in 51 bytes (1 switches on core 0) Is there some additional config that I seem to have missed? Would greatly appreciate your time and input. I will leave a solution in case I find one. Best...
You may want to check the section on the django docs about serving static files. The rules for mod_wsgi apply to mod_uwsgi. A more easy approach is configuring uWSGI to serve static files: http://uwsgi-docs.readthedocs.org/en/latest/StaticFiles.html Check the part about offloading if your site is pretty loaded Generally avoid using django for serving static files
I am not using nginx but Apache, running mod_wsgi. There I have the possibility to use Alias /static/ /var/www/django-project/static/ All files are in my directory and accesaible at http://example.com/static/. So maybe you can do the same with nginx. Edit: This skips the process of wsgi/cgi/uwsgi and allows the http daemon to handle the static files directly. There is no need for python to parse these kind of requests - because they're only accessing static files.