本篇介紹如何在 Linux 系統中自行建立一個網路伺服器,並設定讓 Systemd 自動啟動與管理伺服器的運作。
建立 Echo 伺服器
首先以 Python 撰寫一個簡單的 echo 伺服器,將其儲存在 /opt/echo_server.py:
#!/usr/bin/env python3
import socket
# 建立 socket
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定所有網路介面的 9000 連接埠
serv.bind(('0.0.0.0', 9000))
# 開始接受 client 連線
serv.listen()
while True:
# 接受 client 連線
conn, addr = serv.accept()
print('Client from', addr)
while True:
# 接收資料
data = conn.recv(1024)
# 若無資料則離開
if not data: break
# 傳送資料
conn.send(data)
conn.close()
print('Client disconnected')
這段 Python 程式碼在執行之後,會傾聽所有網路介面的 9000 連接埠,建立連線之後將所有收到的資料送回 client 端。
建立好 /opt/echo_server.py 之後,順便開啟執行權限:
# 開啟執行權限
chmod +x /opt/echo_server.py
我們可以先手動測試一下,啟動 echo 伺服器:
# 啟動 echo 伺服器(server 端)
/opt/echo_server.py
接著開啟另外一個終端機,使用 nc 指令連線至 9000 連接埠
# 連線至 localhost 的 9000 連接埠(client 端)
nc localhost 9000
連上之後,隨意輸入一些文字,送出之後應該就會看到伺服器回應相同的文字,而在伺服器端應該也會顯示一些關於 client 的資訊,這樣就代表 echo 伺服器可以正常運作了。
建立 Systemd 服務單位設定檔
建立一個新的 Systemd 服務單位設定檔,儲存於 /etc/systemd/system/echo_server.service:
[Unit]
Description=Echo Server
[Service]
Type=simple
ExecStart=/opt/echo_server.py
Restart=always
[Install]
WantedBy=multi-user.target
權限要設定為 644:
sudo chmod 644 /etc/systemd/system/echo_server.service
如果在開發過程中,有修改過 Systemd 的服務單位設定檔,記得重新載入 daemon 讓新設定生效:
# 重新載入 Systemd 設定檔
sudo systemctl daemon-reload
接著就可以使用 systemctl 指令啟動自訂的 echo 伺服器:
# 啟動自訂的 echo 伺服器
sudo systemctl start echo_server
查看 echo 伺服器的狀態:
# 查看 echo 伺服器狀態
systemctl status echo_server
● echo_server.service - Echo Server
Loaded: loaded (/etc/systemd/system/echo_server.service; disabled; vendor pre
Active: active (running) since Thu 2019-09-19 06:59:46 UTC; 1min 46s ago
Main PID: 20142 (python3)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/echo_server.service
└─20142 python3 /opt/echo_server.py
Sep 19 06:59:46 test-vm systemd[1]: Started Echo Server.這樣就成功啟動了自己開發的 echo 伺服器了,此時我們可以直接使用上面的 nc 指令測試一下伺服器是否正常運作。
如果要停止 echo 伺服器,可執行:
# 停止 echo 伺服器
sudo systemctl stop echo_server
如果想要讓 echo 伺服器可以在開機時自動啟動,可執行:
# 設定開機自動啟動 echo 伺服器
sudo systemctl enable echo_server
Created symlink /etc/systemd/system/multi-user.target.wants/echo_server.service → /etc/systemd/system/echo_server.service.
若要取消開機自動啟動 echo 伺服器,則可執行:
# 取消開機自動啟動 echo 伺服器
sudo systemctl disable echo_server
Removed /etc/systemd/system/multi-user.target.wants/echo_server.service.
關於 systemctl 指令的詳細用法,請參考 Linux systemd 系統服務管理基礎教學文章。
Systemd 服務單位設定檔的完整文件可以從線上手冊查詢:
# 查詢 Systemd 服務單位設定檔說明文件
man systemd.unit
man systemd.service
man systemd.exec
另外亦可從 /lib/systemd/system/(Ubuntu)或 /usr/lib/systemd/system/(CentOS)目錄中找到大量的實際範例。
Systemd 服務單位設定檔範本
以下是一個比較詳細的 Systemd 服務單位設定檔範本,在撰寫自訂服務的設定檔時,可以先複製這份設定再接著修改:
[Unit]
# 服務名稱
Description=Your Server
# 服務相關文件
# Documentation=https://example.com
# Documentation=man:nginx(8)
# 設定服務啟動的先後相依姓,例如在網路啟動之後:
# After=network.target
[Service]
# 行程類型
Type=simple
# 啟動服務指令
ExecStart=/opt/your_command
# 服務行程 PID(通常配合 forking 的服務使用)
# PIDFile=/run/your_server.pid
# 啟動服務前,執行的指令
# ExecStartPre=/opt/your_command
# 啟動服務後,執行的指令
# ExecStartPost=/opt/your_command
# 停止服務指令
# ExecStop=/opt/your_command
# 停止服務後,執行的指令
# ExecStopPost=/opt/your_command
# 重新載入服務指令
# ExecReload=/opt/your_command
# 服務終止時自動重新啟動
Restart=always
# 重新啟動時間格時間(預設為 100ms)
# RestartSec=3s
# 啟動服務逾時秒數
# TimeoutStartSec=3s
# 停止服務逾時秒數
# TimeoutStopSec=3s
# 執行時的工作目錄
# WorkingDirectory=/opt/your_folder
# 執行服務的使用者(名稱或 ID 皆可)
# User=myuser
# 執行服務的群組(名稱或 ID 皆可)
# User=mygroup
# 環境變數設定
# Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6"
# 服務輸出訊息導向設定
# StandardOutput=syslog
# 服務錯誤訊息導向設定
# StandardError=syslog
# 設定服務在 Syslog 中的名稱
# SyslogIdentifier=your-server
[Install]
WantedBy=multi-user.target
