将应用程序 运行 转为 systemd 服务
Go application run as systemd service
我们正在 运行 构建一个内部 运行 自动更新模块以接收无线更新的 Golang 应用程序。在新更新时,自动更新模块从 s3 下载新版本并调用与可执行文件位于同一工作目录中的自动更新 bash 脚本。 autoupdate bash 脚本执行的步骤在使用和不使用 systemd 处理的进程管理方面进行了解释。
不使用 Systemd 执行
- 通过 PID
杀死当前 运行ning golang 应用程序
- 运行新下载的 golang 二进制文件。
- 新版本公开了健康检查API,脚本调用该检查以确保此版本健康。
- 如果不健康,则执行回滚。新版本停止,旧版本启动。
在 golang 中,脚本执行代码被编写为当调用自动更新脚本时,它与 golang 应用程序的生命周期无关。即 bash 脚本(子进程)即使在父进程(golang 应用程序)被杀死后仍继续执行。当从 GoLand 运行ning IDE.
时它工作正常
问题:通过 Systemd 执行
我们需要一个更干净的系统来处理启动、停止、重启失败功能。所以我们决定 运行 应用程序作为 systemd service.The 步骤与上面相同,但使用 systemctl
执行
- 杀死当前 运行ning golang 应用程序:"systemctl stop goapp.service"
- 使用新的可执行路径更新 systemd 服务:"systemctl daemon-reload"
- 重新启动 systemd 服务:"systemctl restart goapp.service"
- 如果不健康,则执行回滚。新版本停止,systemd 服务文件用旧版本更新,旧版本启动。
在通过 systemd 执行应用程序时,在上述第 1 步 中使用命令 "sudo systemctl stop goapp.service" 停止 systemctl 服务后,脚本会立即退出。这意味着 golang 应用程序执行的脚本的生命周期显然与 systemd 服务的生命周期耦合。我怎样才能将它从 systemd 服务的范围中分离出来?
Systemd 服务文件
[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
调用自动更新的Golang代码部分bash脚本
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()
}
"how to run a script in Golang and disown/detach it" 上的帖子已发布,但找不到关于此类问题的任何帖子。如果我的理解有任何错误,请帮助我解决问题或纠正我。
invokes an autoupdate bash script present in the same working directory as the executable.
我会推荐 运行 它和 systemd-run。摘自man-page:
It will run in a
clean and detached execution environment.
我们正在 运行 构建一个内部 运行 自动更新模块以接收无线更新的 Golang 应用程序。在新更新时,自动更新模块从 s3 下载新版本并调用与可执行文件位于同一工作目录中的自动更新 bash 脚本。 autoupdate bash 脚本执行的步骤在使用和不使用 systemd 处理的进程管理方面进行了解释。
不使用 Systemd 执行
- 通过 PID 杀死当前 运行ning golang 应用程序
- 运行新下载的 golang 二进制文件。
- 新版本公开了健康检查API,脚本调用该检查以确保此版本健康。
- 如果不健康,则执行回滚。新版本停止,旧版本启动。
在 golang 中,脚本执行代码被编写为当调用自动更新脚本时,它与 golang 应用程序的生命周期无关。即 bash 脚本(子进程)即使在父进程(golang 应用程序)被杀死后仍继续执行。当从 GoLand 运行ning IDE.
时它工作正常问题:通过 Systemd 执行
我们需要一个更干净的系统来处理启动、停止、重启失败功能。所以我们决定 运行 应用程序作为 systemd service.The 步骤与上面相同,但使用 systemctl
执行- 杀死当前 运行ning golang 应用程序:"systemctl stop goapp.service"
- 使用新的可执行路径更新 systemd 服务:"systemctl daemon-reload"
- 重新启动 systemd 服务:"systemctl restart goapp.service"
- 如果不健康,则执行回滚。新版本停止,systemd 服务文件用旧版本更新,旧版本启动。
在通过 systemd 执行应用程序时,在上述第 1 步 中使用命令 "sudo systemctl stop goapp.service" 停止 systemctl 服务后,脚本会立即退出。这意味着 golang 应用程序执行的脚本的生命周期显然与 systemd 服务的生命周期耦合。我怎样才能将它从 systemd 服务的范围中分离出来?
Systemd 服务文件
[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
调用自动更新的Golang代码部分bash脚本
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()
}
"how to run a script in Golang and disown/detach it" 上的帖子已发布,但找不到关于此类问题的任何帖子。如果我的理解有任何错误,请帮助我解决问题或纠正我。
invokes an autoupdate bash script present in the same working directory as the executable.
我会推荐 运行 它和 systemd-run。摘自man-page:
It will run in a clean and detached execution environment.