昨天我們成功的把 API 程式佈署到 GCP 的 VM 上了。不過,我們有一個問題:只要跑了 .NET 程式,這個 SSH 連線就被佔用了,如果要做其他事就得 ctrl+c 停止 API 程式。這種不方便的事我們當然不允許,今天我們就來把 API 程式包成 Linux service,讓 Linux 的 systemd 幫我們管理我們的程式。
systemd 是現在主流 Linux 版本的服務管理程式,它能幫我們啟動、監控、停止與管理服務,甚至可以在程式掛掉的時候嘗試重啟服務。在把我們的程式託管給 systemd 之前,我們必須先建立代表我們 API 程式的 service unitsudo touch /etc/systemd/system/ironman_api.service
再來,因為 service unit 會需要我們發佈完的檔案,所以先來手動發布一下我們的專案cd /ironman/dotnet_api/IThomeIronman/ # 跳到 API 專案的資料夾
sudo dotnet publish -c Release # 執行 .NET CLI, 以 Release 模式發布方案
接著,用 vim 打開這個 service 檔案sudo vi /etc/systemd/system/ironman_api.service
寫入 service unit 資訊
[Unit]
Description=IThome 2021 ironman API
[Service]
WorkingDirectory=/ironman/dotnet_api/IThomeIronman/Ithome_2021_API/bin/Release/net5.0/
ExecStart=/usr/bin/dotnet /ironman/dotnet_api/IThomeIronman/Ithome_2021_API/bin/Release/net5.0/Ithome_2021_API.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-ironman-api
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://0.0.0.0:80;https://0.0.0.0:443
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
上面的設定檔各個參數解釋如下:
no
建好 service unit 檔案之後,就能用下面這個指令叫 systemd 幫我們啟動、管理我們的 API 程式。sudo systemctl start ironman_api.service
systemctrl 是用來管理 service 的指令,start 代表啟動,後面的 ironman_api.service 是我們放在 /etc/systemd/system/ 資料夾底下建立的 service unit
啟動後,我們可以用 status 指令來檢查這個 service 的狀況,如果亮綠燈就代表成功跑起來了。sudo systemctl status ironman_api.service
啟動完 service,再一次到瀏覽器輸入 https://外部IP/api/User ,可以看到我們的 API 在正常發揮。
全部 OK 之後,我們要來設定「隨著系統啟動」,之前的Restart=always
雖然會在程式掛掉的時候自動嘗試重啟,但是如果 VM 關機或重開機它就會停掉。雖然我們有設定WantedBy=multi-user.target
,但我們還需要一個指令把我們的 service 加到自動啟動名單sudo systemctl enable ironman_api.service
最後分享幾個常用的指令:
systemctl stop ironman_api.service
systemctl restart ironman_api.service
journalctl -fu ironman_api.service
當程式有 bug 掛掉的時候,輸入這個指令就會看到噴錯然後重啟,然後再噴錯再重啟XD