Frage

Ich bin mit einer django Instanz hinter nginx angeschlossen fcgi mit (durch den manage.py runfcgi-Befehl). Da der Code in den Speicher geladen wird, kann ich nicht neuen Code nachladen, ohne töten und die django fcgi Prozesse neu zu starten, damit die Live-Website zu unterbrechen. Das Neustarten selbst ist sehr schnell. Aber durch die fcgi Prozesse zu töten zunächst einige Benutzeraktionen erhalten unterbrochen, was nicht gut ist. Ich frage mich, wie kann ich neuen Code nachladen, ohne jemals eine Unterbrechung verursacht. Ratschläge werden sehr geschätzt werden!

War es hilfreich?

Lösung

Ich möchte einen neuen fcgi Prozess auf einem neuen Port starten, die nginx-Konfiguration ändern den neuen Port zu verwenden, haben nginx Nachladekonfiguration (was an sich anmutig ist), dann schließlich das alte Verfahren stoppen (Sie netstat verwenden können, finden wenn aus der letzten Verbindung zum alten Hafen ist geschlossen).

Alternativ können Sie die fcgi Implementierung ändern, um einen neuen Prozesses, schließen Sie alle Steckdosen im Kind mit Ausnahme des fcgi Server-Socket-Gabel, den fcgi Server-Socket in Mutter schließen, einen neuen django Prozess in dem Kind exec (die es verwendet der fcgi Server-Socket), und beendet den Eltern-Prozess, wenn alle fcgi Verbindungen geschlossen sind. IOW, implementieren ordnungsgemäßen Start für runfcgi.

Andere Tipps

Also ging ich weiter und Martin Vorschlag umgesetzt. Hier ist der Bash-Skript, ich kam mit.

pid_file=/path/to/pidfile
port_file=/path/to/port_file
old_pid=`cat $pid_file`

if [[ -f $port_file ]]; then
    last_port=`cat $port_file`
    port_to_use=$(($last_port + 1))
else
    port_to_use=8000
fi

# Reset so me don't go up forever
if [[ $port_to_use -gt 8999 ]]; then
    port_to_use=8000
fi

sed -i "s/$old_port/$port_to_use/g" /path/to/nginx.conf

python manage.py runfcgi host=127.0.0.1 port=$port_to_use maxchildren=5 maxspare=5 minspare=2 method=prefork pidfile=$pid_file

echo $port_to_use > $port_file

kill -HUP `cat /var/run/nginx.pid`

echo "Sleeping for 5 seconds"
sleep 5s

echo "Killing old processes on $last_port, pid $old_pid"
kill $old_pid

Ich stieß auf dieser Seite, während eine Lösung für dieses Problem suchen. Alles andere versagt, so dass ich sah auf den Quellcode:)

Die Lösung scheint viel einfacher zu sein. Django fcgi Server verwendet flup, die Griffe der HUP die richtige Art und Weise signalisieren: es schaltet sich ab, anmutig. Also alles, was Sie tun müssen, ist:

  1. das HUP Signal an den fcgi Server senden (die pidfile = Argument von runserver wird sich als nützlich)

  2. ein bisschen warten (flup ermöglicht Kinder verarbeitet 10 Sekunden, so dass ein paar mehr warten; 15 sieht aus wie eine gute Anzahl)

  3. schickte das KILL Signal an den fcgi Server, nur für den Fall, dass etwas blockiert es

  4. Starten Sie den Server wieder

Das ist es.

Wir fanden schließlich die richtige Lösung für dieses Problem!

http: //rambleon.usebox. net / post / 3279121000 / how-to-elegant-Neustart-django-running-fastcgi

Zuerst ein HUP-Signal senden flup einen Neustart zu signalisieren. Flup wird dann das tun, um alle seine Kinder:

  1. schließt die Buchse, die inaktiv Kinder stoppen
  2. sendet ein Signal INT
  3. wartet 10 Sekunden
  4. sendet ein KILL-Signal

Wenn alle Kinder verschwunden sind wird es neue beginnen.

Das funktioniert fast die ganze Zeit, mit der Ausnahme, dass, wenn ein Kind ist der Umgang mit einer Anfrage bei der flup Schritt ausführt 2 dann Ihr Server mit KeyboardInterrupt sterben wird, den Benutzer einen 500-Fehler geben.

Die Lösung ist ein SIGINT-Handler zu installieren - die Seite oben für Details. Auch nur SIGINT ignorieren gibt Ihren Prozess 10 Sekunden, um zu beenden, was für die meisten Anfragen genug ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top