Ich habe pm2
für mein Node.js-Skript verwendet und ich liebe es.
Ich habe jetzt ein Python-Skript, das Streaming-Daten auf EC2 sammelt. Manchmal bombardiert das Skript und ich möchte, dass ein Prozessmanager sich wie pm2 neu startet.
Gibt es so etwas wie pm2 für Python? Ich habe herumgesucht und konnte nichts finden.
Hier ist mein Fehler
File "/usr/local/lib/python2.7/dist-packages/tweepy/streaming.py", line 430, in filter
self._start(async)
File "/usr/local/lib/python2.7/dist-packages/tweepy/streaming.py", line 346, in _start
self._run()
File "/usr/local/lib/python2.7/dist-packages/tweepy/streaming.py", line 286, in _run
raise exception
AttributeError: 'NoneType' object has no attribute 'strip'
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:90:
Es ist ein einfaches Skript zum Sammeln von Daten
class StdOutListener(StreamListener):
def on_data(self, data):
mydata = json.loads(data)
db.raw_tweets.insert_one(mydata)
return True
def on_error(self, status):
mydata = json.loads(status)
db.error_tweets.insert_one(mydata)
if __== '__main__':
#This handles Twitter authetification and the connection to Twitter Streaming API
l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)
#This line filter Twitter Streams to capture data by the keywords: 'python', 'javascript', 'Ruby'
stream.filter(follow=[''])
Dass ich möchte, dass es sich einfach neu startet, falls etwas passiert.
UPD: Siehe unten stehende Antworten für bessere Lösungen.
-
Dafür gibt es mehrere Lösungen. Erstens können Sie http://supervisord.org/ verwenden. Hierbei handelt es sich um ein anständiges universelles Prozesssteuerungssystem, das eine Vielzahl von Funktionen enthält, z. B. Autostart, Neustartzähler, Protokollierung, flexible Konfiguration und mehr .
Darüber hinaus können Sie Ihre Implementierungslogik einfach in eine Funktion einbinden, sie im try except
-Block ausführen, alle Ausnahmen abfangen. Wenn eine Ausnahmebedingung angewendet wird, führen Sie die Funktion erneut aus, anstatt das Skript zu beenden. In Ihrem Fall kann eine solche Funktion das Erstellen eines Listeners, einer Authentifizierung und eines Stream-Teils umfassen.
Sie können tatsächlich Python-Skripte von pm2 aus ausführen:
pm2 start echo.py
Wenn das Skript mit einem .py-Suffix endet, wird standardmäßig ein Python-Interpreter verwendet. Wenn Ihr Dateiname nicht mit .py endet, können Sie Folgendes tun:
pm2 start echo --interpreter=python
Ich habe festgestellt, dass Sie ein wenig aufpassen müssen, welchen Python Sie verwenden, insbesondere wenn Sie einen virtualenv-Python mit einer anderen Version als den Standard-Python auf Ihrem Computer verwenden.
PM2 ist genug, es wird Interpreter mit dem Suffix ausgeführt:
{
".sh": "bash",
".py": "python",
".rb": "Ruby",
".coffee" : "coffee",
".php": "php",
".pl" : "Perl",
".js" : "node"
}
In meinem Fall verwende ich Scrapyd in meinem Projekt. Der ursprüngliche Befehl lautet:
scrapyd --pidfile /var/log/scrapyd/twistd.pid -l /var/log/scrapyd/logs/scrapyd.log
und die pm2-Version ist:
pm2 start scrapyd --interpreter python --watch --name=scrapyd -- --pidfile "/var/log/scrapyd/twistd.pid" -l "/var/log/scrapyd/logs/scrapyd.log"
ich hoffe, dieses Beispiel kann helfen
PM2 mit pipenv
Für diejenigen, die versuchen, ein python Programm von/mit pipenv auszuführen, versuchen Sie ein pm2.config.json (oder ecosystem.json.config als in der offiziellen Dokumentation von PM2) wie folgt:
Die wichtigen Teile sind "interpreter" : "pipenv"
Und "interpreter_args": "run python3"
.
pm2.config.json
{
"apps": [{
"name": "BackupService",
"script": "/home/service-backup/service/server.py",
"args": [""],
"wait_ready": true,
"autorestart": false,
"max_restarts": 5,
"interpreter" : "pipenv",
"interpreter_args": "run python3"
}]
}
Dann pm2 start pm2.config.json
. Ich habe immer pm2 delete BackupService
(Oder wie auch immer Sie es in "Name" nennen), bevor ich wieder anfange, weil selbst mit dem --update-env
Flag kein aktualisierter pm2.config.json
Verwendet wird. Ich weiß nicht warum.
Beachten Sie auch, dass "interpreter_args"
Nach den neuesten PM2-Dokumenten anscheinend in "node_args"
Geändert wurde. Ich verwende pm2 --version
3.0.0 und der alte Weg funktioniert immer noch.
PM2 mit Python Multiprocessing
Wenn Sie ein python) - Programm ausführen möchten, das Pythons Multiprocessing Lib verwendet, müssen Sie die Ausführung im fork -Modus erzwingen. PM2 versucht es, falls nicht anders angegeben, automatisch es im cluster
Modus laufen zu lassen, scheint.
Ich vermute jedoch, dass wir den Multiprocessing-Teil Python= vollständig überlassen müssen. Ich kann mir nicht vorstellen, dass PM2 in der Lage ist, die verschiedenen Prozesse zu verwalten, die durch das Multiprocessing von Python - was es versucht, wenn es im cluster
Modus läuft.Auch wenn die "interpreter"
Option (zB für pipenv) verwendet wird, funktioniert nur fork_mode
Entsprechend die PM2 docs.
Fügen Sie also "exec_mode": "fork"
Zu Ihrem pm2.config.json
Hinzu, damit es ausgeführt wird.
Wenn Sie keine pm2.config.json
- Datei verwenden, sollte die Übergabe von -i 0
An pm2 start
Auch den Fork-Modus erzwingen. (-i steht für Instanzen)
Ich habe eine Echosystemdatei erstellt echosystem.config.json
{
"apps": [{
"name": "app_name",
"script": "/the/app/path/my_app.py",
"args": ["-c", "my_config.prod.json"],
"instances": "1",
"wait_ready": true,
"autorestart": false,
"max_restarts": 5,
"interpreter" : "/path/to/venv/bin/python",
}]
}
Führen Sie den pm2-Dienst aus:
$ pm2 start echosystem.config.json
$ pm2 -v
3.2.8