
Ich versuche, mit systemd einen Dienst zu erstellen, bei dem ich mit Python3 einen einfachen Socket erstelle und ihn als Daemon belasse. Ich habe mehrere Versuche unternommen, aber beide Male ohne Erfolg. Für heute hat systemd mich besiegt, aber morgen ist ein neuer Tag, um es zu versuchen.
Server
import socket
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.bind((host, port))
socket_tcp.listen(5) # Esperamos la conexión del cliente
conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente
with conn:
print('[*] Conexión establecida')
while True:
# Recibimos bytes, convertimos en str
data = conn.recv(BUFFER_SIZE)
# Verificamos que hemos recibido datos
if not data:
break
else:
print('[*] Datos recibidos: {}'.format(data.decode('utf-8')))
conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes
Client
import socket
# El cliente debe tener las mismas especificaciones del servidor
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024 MESSAGE = 'Hola, mundo!' # Datos que queremos enviar with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.connect((host, port))
# Convertimos str a bytes
socket_tcp.send(MESSAGE.encode('utf-8'))
data = socket_tcp.recv(BUFFER_SIZE)
Konfigurationseinheitsdatei
sudo nano /etc/systemd/system/socket_prueba.service
sudo rm -r /etc/systemd/system/socket_prueba.service
[Unit]
Description= Server Relay System: Manager
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/pipenv run python /path/test_server.py
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable socket_prueba.service
sudo systemctl start socket_prueba.service
sudo systemctl status socket_prueba.service
Ergebnis:
● socket_prueba.service - Server Relay System: Manager
Loaded: loaded (/etc/systemd/system/socket_prueba.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2021-09-25 16:07:17 -05; 58min ago
Process: 25771 ExecStart=/usr/local/bin/pipenv run python
/home/path>
Main PID: 25771 (code=exited, status=2)
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Scheduled restart job, restart counter is >
sep 25 16:07:17 serversaas systemd[1]: Stopped Server Relay System: Manager.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Start request repeated too quickly.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Failed with result 'exit-code'.
sep 25 16:07:17 serversaas systemd[1]: Failed to start Server Relay System: Manager.
Absicht 2 Quelle:systemd und python
● socket_prueba.socket - Socket prueba
Loaded: loaded (/etc/systemd/system/socket_prueba.socket; disabled; vendor preset: enabled)
Active: failed (Result: service-start-limit-hit) since Sat 2021-09-25 17:00:47 -05; 4s ago
Triggers: ● socket_prueba.service
Listen: 127.0.0.1:9999 (Stream)
sep 25 17:00:47 vidm-OMEN systemd[1]: Listening on Socket prueba.
sep 25 17:00:47 vidm-OMEN systemd[1]: socket_prueba.socket: Failed with result 'service-start-limit-hit'.
Antwort1
Hier sind einfache Shell-Bereitstellungsbefehle für Ihren Fall, die sofort einsatzbereit sind. Sie können Verzeichnisse, Namen, Beschreibungen von Diensten oder Skripts usw. ändern. Die Beschreibung finden Sie weiter unten:
Verzeichnis und Skript selbst erstellen
mkdir /usr/src/python-socket -p
cat > /usr/src/python-socket/python-socket.py << 'EOL'
import socket
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.bind((host, port))
socket_tcp.listen(5) # Esperamos la conexión del cliente
conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente
with conn:
print('[*] Conexión establecida')
while True:
# Recibimos bytes, convertimos en str
data = conn.recv(BUFFER_SIZE)
# Verificamos que hemos recibido datos
if not data:
break
else:
print('[*] Datos recibidos: {}'.format(data.decode('utf-8')))
conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes
EOL
Einrichten von Variablen zum Erstellen des Systemd-Dienstes
SERVICE_NAME=python-socket
SERVICE_DESCRIPTION="Test python service"
SERVICE_COMMAND="/usr/bin/python3 /usr/src/python-socket/python-socket.py"
SERVICE_WORK_DIR=/usr/src/python-socket/
SERVICE_USER=root
Bereitstellen der systemd-Dienstkonfiguration
cat > /etc/systemd/system/${SERVICE_NAME}.service << EOL
[Unit]
Description=${SERVICE_DESCRIPTION}
After=multi-user.target
[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=${SERVICE_WORK_DIR}
Type=simple
User=${SERVICE_USER}
ExecStart=${SERVICE_COMMAND}
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process
[Install]
WantedBy=multi-user.target
EOL
Neuen Dienst beantragen, starten und prüfen
systemctl daemon-reload
systemctl enable ${SERVICE_NAME}
systemctl stop ${SERVICE_NAME}
systemctl start ${SERVICE_NAME}
systemctl status ${SERVICE_NAME}
Als Ergebnis sieht Ihre systemd-Dienstkonfiguration wie folgt aus:
[Unit]
Description=Test python service
After=multi-user.target
[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=/usr/src/python-socket/
Type=simple
User=root
ExecStart=/usr/bin/python3 /usr/src/python-socket/python-socket.py
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process
[Install]
WantedBy=multi-user.target
Wo:
Environment="FROM=SYSTEMD"
- einige Umgebungsvariablen, wenn Sie sie an Ihr Python-Skript übergeben möchten
Type=simple
- einfacher systemd-Dienst, der funktioniert, während das Skript aktiv ist
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
Diese Parameter verhindern, dass Ihr Skript unter irgendwelchen Bedingungen ausfällt, es wird bei einem Fehler kontinuierlich gestartet
KillMode=process
- So wird Ihr Skript beendet. Wenn Sie in Ihrem Python-Skript keine speziellen SIG-Ereignisse haben, ist es universell