Como faço para criar um serviço python 3 que usa soquete com systemd?

Como faço para criar um serviço python 3 que usa soquete com systemd?

Estou tentando criar um serviço com systemd, onde utilizo o python3 para criar um soquete simples e deixá-lo como um daemon, mas fiz diversas tentativas mas em ambos os casos sem sucesso. Por hoje o systemd me venceu, mas amanhã é outro dia para tentar.

Servidor

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)

Arquivo de unidade de configuração

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

Resultado:

● 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.

Intenção 2 Fonte:systemd e python

soquete com python e systemd

● 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'.

Responder1

Aqui estão os comandos simples de implantação do shell para o seu caso, você pode alterar diretórios, nome, descrição do serviço ou script e assim por diante, a descrição está abaixo:

Crie o diretório e o próprio script

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

Configure variáveis ​​para criar serviço systemd

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

Implantar configuração de serviço systemd

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

Aplique o novo serviço, inicie-o e verifique

systemctl daemon-reload
systemctl enable ${SERVICE_NAME}
systemctl stop ${SERVICE_NAME}
systemctl start ${SERVICE_NAME}
systemctl status ${SERVICE_NAME}

Como resultado, sua configuração de serviço do systemd será semelhante a

[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

Onde:

Environment="FROM=SYSTEMD"- alguma variável env se você quiser passar para o seu script python

Type=simple- serviço systemd simples que funcionará enquanto o script estiver ativo

RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0

Esses parâmetros não permitirão que seu script fique inativo em quaisquer condições, ele iniciará e falhará continuamente

KillMode=process- É assim que seu script irá parar, se você não tiver eventos SIG especiais em seu script python, ele é universal

informação relacionada