web-dev-qa-db-fra.com

"connexion fermée prématurément en amont lors de la lecture de l'en-tête de réponse en amont" Django, Ubuntu, Nginx, Gunicorn

J'ai déployé un site Web Django en utilisant ce tutoriel

https://jee-appy.blogspot.com/2017/01/deply-Django-with-nginx.html

Le site Web est accessible sur Internet, www.simplesol.com

Lorsque j'essaie de faire une demande POST, elle échoue et j'obtiens une erreur 502.

Dans mon fichier nginx-error.log, je reçois ce message d'erreur

*344 upstream prematurely closed connection while reading response header 
from upstream, client: InternalIP, server: ExternalIP, request: "POST 
/audit/ HTTP/1.1", upstream: 
"http://unix:/home/webadmin/virtual_env/run/gunicorn.sock:/audit/", Host: 
"www.simplesol.com", referrer: "http://www.simplesol.com/audit/"

Ce sont les contenus de mon /etc/nginx/sites-available/simplesol.conf

command = /home/webadmin/gunicorn_start.bash                   ;  Command to start app
user = webadmin                                                ; User to run as
stdout_logfile = /home/webadmin/logs/gunicorn_supervisor.log   ; Where to write log messages
redirect_stderr = true                                       ; Save stderr in the same log
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8              ; Set UTF-8 as default encoding

/etc/nginx/sites-available/simplesol.conf

upstream 192.168.8.5 {

server unix:/home/webadmin/adrienne/run/gunicorn.sock fail_timeout=0;
}

server {

    listen   80;
server_name 192.168.8.5 ;

client_max_body_size 4G;
access_log /home/webadmin/logs/nginx-access.log;
error_log /home/webadmin/logs/nginx-error.log;

location /static/ {
    autoindex on;
    alias /home/webadmin/static/;
}

location /media/ {
    alias   /home/webadmin/media/;
location / {

    # an HTTP header important enough to have its own Wikipedia entry:
    #   http://en.wikipedia.org/wiki/X-Forwarded-For
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


    # enable this if and only if you use HTTPS, this helps Rack
    # set the proper protocol for doing redirects:
    #proxy_set_header X-Forwarded-Proto https;

    # pass the Host: header from the client right along so redirects
    # can be set properly within the Rack application
    proxy_set_header Host $http_Host;

    # we don't want nginx trying to do something clever with
    # redirects, we set the Host: header above already.
    proxy_redirect off;

    # set "proxy_buffering off" *only* for Rainbows! when doing
    # Comet/long-poll stuff.  It's also safe to set if you're
    # using only serving fast clients with Unicorn + nginx.
    # Otherwise you _want_ nginx to buffer responses to slow
    # clients, really.
    proxy_buffering off;

    # Try to serve static files from nginx, no point in making an
    # *application* server like Unicorn/Rainbows! serve static files.
    if (!-f $request_filename) {
        proxy_pass http://192.168.8.5;
        break;
    }
}

# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
    root /home/webadmin/SimpleSolWebsite/static/;
}
   }

gunicorn_start.bash

#!/bin/bash

NAME="Django_app"                                   
DJANGODIR=/home/ubuntu/sample_project               
SOCKFILE=/home/ubuntu/Django_env/run/gunicorn.sock  
USER=ubuntu                                         
GROUP=ubuntu                                        
NUM_WORKERS=3                                       
Django_SETTINGS_MODULE=sample_project.settings              
Django_WSGI_MODULE=sample_project.wsgi              
echo "Starting $NAME as `whoami`"



cd $DJANGODIR
source /home/ubuntu/Django_env/bin/activate
export Django_SETTINGS_MODULE=$Django_SETTINGS_MODULE
 export PYTHONPATH=$DJANGODIR:$PYTHONPATH



RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR



exec gunicorn ${Django_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=-

Y a-t-il un problème avec mes fichiers de configuration? Je ne sais pas où je me suis trompé et je n'ai eu aucun succès sur Google. Merci d'avance pour tout aperçu que vous avez pour moi!

gunicorn_supervisor_log

[2018-03-14 22:23:22 +0000] [25559] [DEBUG] GET /contact/
[2018-03-14 22:23:51 +0000] [10934] [DEBUG] POST /contact/
[2018-03-14 15:24:21 -0700] [24869] [CRITICAL] WORKER TIMEOUT (pid:10934)
[2018-03-14 22:24:21 +0000] [10934] [INFO] Worker exiting (pid: 10934)
[2018-03-14 15:24:21 -0700] [23688] [INFO] Booting worker with pid: 23688

App Contacts

models.py

from Django.db import models


class Contacts(models.Model):
    contact_name = models.CharField(max_length=256, default='contact name')
    phone_number = models.CharField(max_length=15)
    phone_ext = models.CharField(max_length=10, default='ext', blank="True")
    email = models.EmailField()
    comments = models.TextField()
    company_name = models.CharField(max_length=250, default='company name')

forms.py

from Django import forms
from contacts.models import Contacts
from Django.forms import ModelForm
from Django.db import models

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contacts
        fields = "__all__"

views.py

from Django.shortcuts import render
from Django.views.generic.edit import FormView
from contacts.forms import ContactForm
from Django.views.generic import TemplateView
from exchangelib import *
from exchangelib.items import *

class ContactRequestView(FormView):
    template_name = 'contact_form.html'
    form_class = ContactForm
    success_url = '/contact/thanks/'


    def form_valid(self, form):
        credentials = Credentials(
           username='simplesol.com\\jbobst',
           password='password'
       )
        account = Account(
            primary_smtp_address='[email protected]',
            credentials=credentials,
            autodiscover=True,
            access_type=DELEGATE
            )
        audit_request = ''
        for k in form.cleaned_data:
            audit_request += k + ' = ' + form.cleaned_data[k] + '\n'

        m = Message(
            account=account,
            subject='You have a new site audit request',
            body= audit_request,
            to_recipients=
    ['[email protected]','[email protected]'],
        )

        m.send_and_save()

        form.save()
        return super().form_valid(form)



class ContactThanksView(TemplateView):
    template_name = 'contact_thanks.html'
4
John Bobst

Le délai d'expiration par défaut de Gunicorn est secondes

Les travailleurs silencieux pendant plus de ces quelques secondes sont tués et redémarrés.

Si un travailleur est tué/redémarré, la connexion au nginx est interrompue et nginx produira l'erreur que vous rencontrez

* 344 connexion prématurément fermée en amont lors de la lecture de l'en-tête de réponse en amont

Ceci est confirmé par l'erreur que vous voyez dans les journaux de gunicorn:

[2018-03-14 22:23:51 +0000] [10934] [DEBUG] POST /contact/
[2018-03-14 15:24:21 -0700] [24869] [CRITICAL] WORKER TIMEOUT (pid:10934)

Donc, modifiez votre code pour tout terminer en ~ 30 secondes (mieux) ou ajustez le délai (pire)

4
ffeast