Golang应用如何保持长期运行
Golang应用如何保持长期运行 我们有一个使用 Gin 框架编写的 Golang REST Web API。在 Windows 服务器上,它在命令窗口中运行。如果有人关闭命令窗口,应用程序就会关闭。
如何解决这个问题?我们能否将其设置为像 Windows 服务一样运行。
2 回复
要让Golang应用在Windows上作为服务长期运行,可以使用以下方法:
方法一:使用sc命令创建Windows服务
# 1. 构建可执行文件
go build -o myapp.exe main.go
# 2. 创建Windows服务
sc create MyGoService binPath= "C:\path\to\myapp.exe" start= auto
# 3. 启动服务
sc start MyGoService
# 4. 查看服务状态
sc query MyGoService
# 5. 停止服务
sc stop MyGoService
# 6. 删除服务
sc delete MyGoService
方法二:使用NSSM(Non-Sucking Service Manager)
NSSM是更友好的Windows服务管理工具:
- 下载NSSM:https://nssm.cc/download
- 安装服务:
# 将nssm.exe放在系统PATH或应用目录
nssm install MyGoService
# 在弹出的GUI中选择你的Go可执行文件
- 命令行安装:
nssm install MyGoService "C:\path\to\myapp.exe"
nssm set MyGoService AppDirectory "C:\path\to\"
nssm start MyGoService
方法三:使用Go的winsvc包(编程方式)
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/gin-gonic/gin"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc/eventlog"
)
var elog debug.Log
type myservice struct{}
func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
changes <- svc.Status{State: svc.StartPending}
// 启动Gin服务器
go startGinServer()
changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}
for {
select {
case c := <-r:
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending}
// 执行清理操作
return false, 0
}
}
}
}
func startGinServer() {
router := gin.Default()
router.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"status": "healthy"})
})
router.GET("/api/data", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Hello from Windows Service"})
})
if err := router.Run(":8080"); err != nil {
elog.Error(1, fmt.Sprintf("Failed to start server: %v", err))
}
}
func main() {
// 判断是否在服务上下文中运行
isIntSess, err := svc.IsAnInteractiveSession()
if err != nil {
log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
}
if !isIntSess {
elog, err = eventlog.Open("MyGoService")
if err != nil {
log.Fatalf("failed to open event log: %v", err)
}
defer elog.Close()
elog.Info(1, "Starting MyGoService")
err = svc.Run("MyGoService", &myservice{})
if err != nil {
elog.Error(1, fmt.Sprintf("Service failed: %v", err))
return
}
elog.Info(1, "MyGoService stopped")
} else {
// 交互式运行(调试用)
startGinServer()
}
}
方法四:使用WinSW(Windows Service Wrapper)
创建 myapp.xml 配置文件:
<service>
<id>MyGoService</id>
<name>My Go Application</name>
<description>Go REST API Service</description>
<executable>C:\path\to\myapp.exe</executable>
<logpath>C:\logs\myapp</logpath>
<log mode="roll-by-size">
<sizeThreshold>10240</sizeThreshold>
<keepFiles>8</keepFiles>
</log>
<onfailure action="restart" delay="10 sec"/>
</service>
安装服务:
# 下载WinSW:https://github.com/winsw/winsw/releases
winsw.exe install myapp.xml
winsw.exe start myapp.xml
方法五:使用任务计划程序
- 打开"任务计划程序"
- 创建基本任务
- 触发器设置为"计算机启动时"
- 操作设置为"启动程序",选择你的Go可执行文件
- 勾选"不管用户是否登录都要运行"
这些方法都能确保你的Gin应用在Windows服务器上作为服务长期运行,不会因命令窗口关闭而停止。

