我是靠谱客的博主 外向大白,最近开发中收集的这篇文章主要介绍gin 项目作为windows服务运行前言一、代码如下总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

在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服务运行前言一、代码如下总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部