
私は systemd でサービスを作成しようとしています。ここでは、python3 を使用して単純なソケットを作成し、それをデーモンとして残していますが、何度か試してみましたが、どちらの場合も成功しませんでした。今日は systemd に負けましたが、明日はまた別の日に挑戦します。
サーバ
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)
設定ユニットファイル
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
結果:
● 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.
インテント2 情報源:systemd と 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'.
答え1
ここでは、あなたのケースに適したシンプルなシェル デプロイ コマンドが準備されています。ディレクトリ、名前、サービスまたはスクリプトの説明などを変更できます。説明は以下の通りです。
ディレクトリとスクリプト自体を作成する
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
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
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
新しいサービスを適用し、起動して確認する
systemctl daemon-reload
systemctl enable ${SERVICE_NAME}
systemctl stop ${SERVICE_NAME}
systemctl start ${SERVICE_NAME}
systemctl status ${SERVICE_NAME}
結果として、systemdサービスの設定は次のようになります。
[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
どこ:
Environment="FROM=SYSTEMD"
- Python スクリプトに渡したい環境変数
Type=simple
- シンプルな systemd サービス。スクリプトが起動している間は動作します。
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
これらのパラメータにより、スクリプトがどのような状況でもダウンすることはなくなり、継続的に失敗して起動するようになります。
KillMode=process
- これはスクリプトが停止する方法です。Pythonスクリプトに特別なSIGイベントがない場合は、これは普遍的です。