概述
前言
在windows操作系统上是没有守护进程的说法,golang原生不支持注册成windows服务,如果想要实现windows服务,就需要借助第三方库 github.com/kardianos/service 这里以 gin 框架做为 web项目,实现windows服务的效果。(这里记录一下)
一、代码如下
1.代码示例
package main
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
"github.com/kardianos/service"
"io"
"log"
"net/http"
"os"
"path/filepath"
)
type Services struct {
Log service.Logger
Srv *http.Server
Cfg *service.Config
}
// 获取可执行文件的绝对路径
func ExecPath() string {
file, e := os.Executable()
if e != nil {
log.Printf("Executable file path error : %sn", e.Error())
}
path := filepath.Dir(file)
return path
}
// 获取 service 对象
func getSrv() service.Service {
File, err := os.Create(ExecPath() + "/http-server.log")
if err != nil {
File = os.Stdout
}
defer File.Close()
log.SetOutput(File)
s := &Services{
Cfg: &service.Config{
Name: "goWeb",
DisplayName: "goWeb",
Description: "基于gin的web服务",
}}
serv, er := service.New(s, s.Cfg)
if er != nil {
log.Printf("Set logger error:%sn", er.Error())
}
s.Log, er = serv.SystemLogger(nil)
return serv
}
// 启动windows服务
func (srv *Services) Start(s service.Service) error {
if srv.Log != nil {
srv.Log.Info("Start run http server")
}
go srv.StarServer()
return nil
}
// 停止windows服务
func (srv *Services) Stop(s service.Service) error {
if srv.Log != nil {
srv.Log.Info("Start stop http server")
}
log.Println("Server exiting")
return srv.Srv.Shutdown(context.Background())
}
// 运行gin web服务
func (srv *Services) StarServer() {
gin.DisableConsoleColor()
// 创建记录日志的文件
f, _ := os.Create(ExecPath() + "/gin.log")
gin.DefaultWriter = io.MultiWriter(f)
router := gin.Default()
router.GET("/test", func(c *gin.Context){
c.String(http.StatusOK, "Welcome Gin Server")
})
srv.Srv = &http.Server{
Addr: ":8080",
Handler: router,
}
srv.Srv.ListenAndServe()
}
func main() {
s := getSrv()
if len(os.Args) > 1 {
switch os.Args[1] {
case "install":
err := s.Install()
if err != nil {
log.Fatalf("Install service error:%sn", err.Error())
}
fmt.Printf("服务已安装")
case "uninstall":
err := s.Uninstall()
if err != nil {
log.Fatalf("Uninstall service error:%sn", err.Error())
}
fmt.Printf("服务已卸载")
case "start":
err := s.Start()
if err != nil {
log.Fatalf("Start service error:%sn", err.Error())
}
fmt.Printf("服务已启动")
case "stop":
err := s.Stop()
if err != nil {
log.Fatalf("top service error:%sn", err.Error())
}
fmt.Printf("服务已关闭")
}
return
}
err := s.Run()
if err != nil {
log.Fatalf("Run programe error:%sn", err.Error())
}
}
2、运行服务1053错误
错误描述
启动windows服务时提示,“无法启动XXX服务,错误 1053:服务没有及时响应启动或控制请求”,错误原因有以下两个原因:
- 项目初始化时间过长,windows服务启动时间是毫秒级的,如果初始加载太多东西,会导致服务启动时间过长然后报1053错误。
解决办法:建议 start windows 服务时,新开一个协程单独启动 web 服务。比如:示例中: go srv.StarServer() 这里单独一个协程启动web服务器
- 项目中有读写文件,比如:读配置文件。直接 go run 命令运行项目时没有任何问题,作为windows服务启动时报错。这是由于windows服务启动exe文件后的工作目录,并不是exe文件的所在目录,而是变更到了C:WindowsSystem32,所以如果配置文件是相对路径,那么这样是找不到配置文件的,就会报错1053
解决办法: 如果项目中有读写文件,加载配置时,使用绝对路径。
参考文章:
Go1.9windows创建服务小实例.
使用Kardianos创建Go Service.
总结
golang项目使用第三方库轻松实现windows服务,但是也有一些坑,例如上面的1053错误。切记读取配置文件要用绝对路径、使用单独协程来启动web服务。
最后
以上就是外向大白为你收集整理的gin 项目作为windows服务运行前言一、代码如下总结的全部内容,希望文章能够帮你解决gin 项目作为windows服务运行前言一、代码如下总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复