Ein Update auf das Folgende:
Ich habe ein ähnliches Problem bei einem nicht verwandten Skript auf einer virtuellen Debian-Maschine in einem anderen Rechenzentrum festgestellt.
Dies sieht verdächtig aus wie das hier beschriebene Problem (und wie die Person, die diese Frage stellt, habe ich keinen Proxy vor dem Server konfiguriert).
Der Hauptunterschied zur folgenden Beschreibung besteht darin, dass ich beim Anhängen an den hängengebliebenen Prozess recvfrom
eher einen Aufruf sehe als read
:
$ strace -p 17527
Process 17527 attached - interrupt to quit
recvfrom(3,
Python hat jedoch keinen Eindruck davon, dass es sich um einen Proxy handelt:
>>> import os; print os.getenv("HTTP_PROXY"), os.getenv("http_proxy")
None, None
Also bin ich immer noch ratlos. Leider ist die verknüpfte Frage auch ohne endgültige Antwort.
(Ich frage mich auch, ob diese Frage verwandt ist, aber es ist unwahrscheinlich, dass S3 die Überschriften nicht Connection: close
berücksichtigt.)
Ich habe mehrere Debian-Server (Wheezy, x86_64), die alle das folgende Verhalten aufweisen:
Alle Server verfügen über eine Reihe von Cron-Jobs, die unter anderem Daten aus S3 abrufen. Diese laufen normalerweise einwandfrei, zeigen jedoch gelegentlich ps aux
, dass einige der vor Stunden oder Tagen gestarteten Jobs noch ausgeführt werden und nicht sauber abgeschlossen wurden.
Wenn Sie sie mit strace -p <pid>
Shows überprüfen, wird der Prozess in jedem Fall an einen Lesebefehl gehängt. Die Ausgabe eines Prozesses, den ich gerade überprüft habe, war beispielsweise:
$ strace -p 12089
Process 12089 attached - interrupt to quit
read(5,
Wenn ich die Deskriptoren für geöffnete Dateien überprüfe, habe ich Folgendes:
$ sudo lsof -i | grep 12089
python 12089 user 5u IPv4 809917771 0t0 TCP my.server.net:35427->185-201.amazon.com:https (ESTABLISHED)
Zuerst nahm ich an, dass dies nur darauf zurückzuführen ist, dass in den Python-Skripten kein Lesezeitlimit festgelegt wurde. Dies scheint jedoch aus mehreren Gründen nicht der Fall zu sein:
- Dies ist nicht der Fall, wenn auf unseren OS X-Boxen (alle 10.5, i386) dieselben Jobs mit identischem Code ausgeführt werden.
- Eine Variante des Skripts , das nicht ein Timeout - Set (60 Sekunden, unter Verwendung von
socket.setdefaulttimeout
- dies ist in Python 2.7, aber die Code - Basis hat 2,5 kompatibel sein) ist seit gestern worden hängt. - Ein anderer Prozess, der nicht Python ist, scheint gelegentlich ein ähnliches Verhalten aufzuweisen. In diesem Fall führt ein Python-Skript einen
svn up --non-interactive
Prozess aus (unter Verwendung dessensubprocess.Popen
, was das wert ist).
Die Situation mit diesem SVN-Prozess ist ähnlich.
Python wartet auf SVN:
$ strace -p 28034
Process 28034 attached - interrupt to quit
wait4(28127,
Und SVN wartet auf einen read
Anruf:
$ strace -p 28127
Process 28127 attached - interrupt to quit
read(6,
Und diese Lesung zeigt auf einen anderen externen Host:
$ sudo lsof -i | grep 28127
svn 28127 user 3u IPv4 701186417 0t0 TCP my.server.net:49299->sparrow.telecommunity.com:svn (ESTABLISHED)
svn 28127 user 6u IPv4 701186439 0t0 TCP my.server.net:49309->sparrow.telecommunity.com:svn (ESTABLISHED)
(In dem zu aktualisierenden Verzeichnis scheint eine svn:externals
Eigenschaft festgelegt zu ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
sein. Aufgrund ihrer Website wird dies meiner Meinung nach zu telekommunity.com umgeleitet.)
Zusätzliche möglicherweise relevante Punkte:
- Die Python-Umgebung auf den Macs ist 2.5. Auf den Debian-Boxen ist es 2.7.
- Ich bin nicht gut mit SVN vertraut und ich habe keine Ahnung, ob der Grund, warum es hängt, im Grunde der gleiche ist oder nicht. Ich bin mir auch nicht ganz sicher, welche Auswirkungen dies hat
svn:externals
. Dies wurde vor meiner Zeit eingerichtet. - Die Python-Skripte selbst rufen große Datenblöcke (in einigen Fällen ~ 10 MB) von Amazon S3 ab, und dies ist in der Regel langsam (ich sehe Downloadzeiten von bis zu drei Minuten, was im Vergleich zu wie lange lang erscheint Es dauert lange, bis die Server - auch in verschiedenen Rechenzentren - miteinander kommunizieren. In ähnlicher Weise sind einige unserer SVN-Repositorys ziemlich groß. Das heißt also im Grunde, dass einige dieser Operationen ohnehin schon lange dauern, in einigen Fällen jedoch auch stunden- oder tagelang hängen bleiben .
- Auf einem Server hat der OOM-Killer heute Morgen MySQL entfernt. Bei näherer Betrachtung lag die Speichernutzung bei 90% und die Swap-Nutzung bei 100% (wie von Monit gemeldet). Durch das Beenden eines großen Rückstands an blockierten Python-Jobs wurden diese Statistiken auf 60% bzw. 40% reduziert. Dies gibt mir den Eindruck, dass zumindest einige (wenn nicht alle) Daten heruntergeladen / gelesen werden (und im Speicher gehalten werden, während der Prozess hängt).
- Diese Cron-Jobs fordern eine Liste der Ressourcen von S3 an und aktualisieren eine Liste der MySQL-Tabellen entsprechend. Jeder Job wird mit derselben Liste gestartet. Daher wird versucht, dieselben Ressourcen anzufordern und dieselben Tabellen zu aktualisieren.
Ich konnte etwas Verkehr von einem der blockierten Prozesse erfassen; es ist alles ein bisschen unergründlich für mich, aber ich frage mich, ob es anzeigt, dass die Verbindung aktiv ist und funktioniert, nur sehr, sehr langsam? Ich habe es als Kern bereitgestellt, um Unordnung zu vermeiden (ich sollte beachten, dass dies eine Erfassung im Wert von etwa zwei Stunden ist): https://gist.github.com/petronius/286484766ad8de4fe20bDies war ein roter Hering, denke ich. Es gibt Aktivitäten an diesem Port, aber es ist nicht die gleiche Verbindung wie an S3 - es ist nur eine andere zufällige Serveraktivität.- Ich habe versucht, dieses Problem auf einer Box in einem anderen Rechenzentrum (einer VM, auf der dieselbe Version von Debian mit demselben System-Setup ausgeführt wird) ohne Glück neu zu erstellen (ich hatte gedacht, dass das Problem möglicherweise mit diesem Problem zusammenhängt) . Bei den Boxen, bei denen diese Probleme auftreten, handelt es sich jedoch nicht um VMs, und es gibt keine verworfenen Pakete gemäß
ifconfig
). Ich denke, dies deutet auf ein Problem mit der Netzwerkkonfiguration hin, bin mir aber nicht sicher, wo ich damit anfangen soll.
Meine Fragen sind also:
- Kann ich dies auf Systemebene beheben oder läuft bei jedem einzelnen Prozess etwas schief?
- Gibt es etwas grundlegend anderes an der Verarbeitung von
read
Anrufen durch OS X und Linux, das ich wissen muss, um unendlich hängende Prozesse zu vermeiden?
Antworten:
Es ist schwer zu sagen, da nicht bekannt ist, was auf Protokollebene geschieht. Grundsätzlich
read(2)
blockiert der Wille auf unbestimmte Zeit: -Nun kann es sein, dass etwas mit dem Prozess nicht stimmt, z. B. erwartet das andere Ende zuerst eine Antwort von Ihnen, bevor Sie weitere Daten senden, oder eine vorherige Antwort vom anderen Ende erwartet, dass SVN etwas anderes tut, bevor weitere Daten angefordert werden. Angenommen, es wurde eine Fehlerantwort zurückgegeben, die den Client zwingen sollte, einige Informationen erneut zu senden.
Sie können dies nicht ordnungsgemäß beheben, da es unmöglich ist, anhand der Informationen zu bestimmen, was der Absender dieser Daten von Ihnen erwartet. Es gibt jedoch einige Möglichkeiten, um das Problem zu vermeiden und es zu melden.
wait
in einem einfachen Blockiermodus läuftwait
und konfiguriert einen Alarm im übergeordneten Prozess. Wenn der Vorgang nicht innerhalb eines festgelegten Zeitraums abgeschlossen werden kann, können Sie ihn beenden und melden, dass dies geschehen ist. Ein billiger Weg, dies zu tun, besteht darin, den Unterprozess zu ändern. Öffnen Sie, um dentimeout
Befehl aufzurufen .socket
um dem Empfänger auch eine Zeitüberschreitung hinzuzufügen. Beides ist nicht trivial. Dies kannsvn
zu unerwartetem Verhalten führen.Ich kenne die Antwort darauf nicht, aber wenn sich beide positiv verhalten, sollten sie sich beide gleich verhalten. Wenn Sie versuchen, von einem Socket zu lesen, der noch nicht bereit ist, Ihnen Daten zu senden, die den Stream auf unbestimmte Zeit blockieren, ist dies das erwartete Verhalten.
Insgesamt denke ich, dass Ihre beste Angriffsmöglichkeit darin besteht, zu erwarten, dass Ihr
svn
Befehl innerhalb eines bestimmten Zeitraums abgeschlossen ist. Wenn es es nicht tötet und meldet, dass Sie es getan haben.quelle
socket.settimeout
Option verwenden, um sicherzustellen, dass eine Zeitüberschreitung auftritt.Ich glaube, ich habe die oben beschriebenen Probleme herausgefunden, und das meiste Rätsel rührt von meinem Missverständnis darüber her, was auf den Servern geschah.
Es gab die folgenden grundlegenden Probleme:
Ich lasse diese Antwort hier, um zu erklären, was los war, aber ich werde Matthews akzeptieren, weil er Recht hatte, was die tatsächlich möglichen Probleme waren.
quelle