doutang8098 2019-07-09 13:22
浏览 198
已采纳

将应用程序作为系统服务运行

We are running a Golang application that internally runs an autoupdate module to recieve over the air updates. At the time of a new update, the autoupdate module downloads the new version from s3 and invokes an autoupdate bash script present in the same working directory as the executable. The steps performed by the autoupdate bash script are explained in terms of process management handled with and without systemd.

Execution without Systemd

  1. Kills the currently running golang app via PID
  2. Runs the newly downloaded golang binary.
  3. The new version exposes an health check API which is invoked by script to makesure this version is healthy.
  4. If not healthy, rollback is performed. The new version is stopped and older version is started.

In golang, the script execution code is written such that when autoupdate script is invoked, it is disowned from the lifecycle of the golang application. i.e bash script (child process) continues execution even after the parent(golang app) is killed. It works fine when running from the GoLand IDE.

Issue : Execution via Systemd

We needed a cleaner system to handle the start ,stop, restart-on failure functionalities. So we decided to run the app as a systemd service.The steps are the same as above but performed using systemctl

  1. Kills the currently running golang app : "systemctl stop goapp.service"
  2. Updates the systemd service with the new executable path : "systemctl daemon-reload"
  3. Restarts the systemd service : "systemctl restart goapp.service"
  4. If not healthy, rollback is performed. The new version is stopped, systemd service file is updated with older version and older version is started.

On executing the application via systemd, the script exits as soon as the systemctl service is stopped using command "sudo systemctl stop goapp.service" during step 1 mentioned above. This means that the lifecycle of the script executed by the golang app is clearly coupled to the lifecycle of the systemd service. How can I detach it from the of scope of systemd service?

Systemd service file

[Unit]
Description=Goapp
After=docker.service
Requires=docker.service
Requires=docker-mysql.service
Requires=docker-redis.service
StartLimitInterval=200
StartLimitBurst=5

[Service]
User=root
Environment=AWS_SHARED_CREDENTIALS_FILE=/home/username/.aws/credentials
Restart=on-failure
RestartSec=30
WorkingDirectory=/home/username/go/src/goapp-v2.0.0
ExecStart=/home/username/go/src/goapp-v2.0.0/goexecutable --autoupdate=true

[Install]
WantedBy=multi-user.target

The Golang code section that invokes the autoupdate bashscript

func scriptExecutor(argsliceString []string, remoteVersion *semver.Version, localVersion *semver.Version) {

newVersion := fmt.Sprint(remoteVersion)
previousVersion := fmt.Sprint(localVersion)
argslice := append(argsliceString, newVersion, previousVersion)
scriptParams := append([]string{"./autoupdate-script.sh"}, argslice...)
Info("Autoupdater - New version ", newVersion)
Info("Autoupdater - Existing Version ", previousVersion)
Info("Autoupdater - Executing shell script to upgrade go app.Passing parameters ", scriptParams) // ./autoupdate-script.sh goexecutable 7.1.0 7.0.0
cmd := exec.Command("sudo", scriptParams...)
err := cmd.Start()
if err!=nil{
    Info(err)
}
cmd.Process.Release()

}

Posts on "how to run a script in Golang and disown/detach it" have been posted but could not find any posts on this type of an issue. Please help me resolve the issue or correct me if there are any errors in my understanding.

  • 写回答

1条回答 默认 最新

  • dqj5046 2019-07-09 13:48
    关注

    invokes an autoupdate bash script present in the same working directory as the executable.

    I would recommend running it with systemd-run. Excerpt from the man-page:

    It will run in a clean and detached execution environment.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作