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.

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

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?