go服务运行框架go-svc

go-svc:https://github.com/judwhite/go-svc/svc

go-svc支持linux和windows,应用只需实现Service接口即可。

官方例子

package main

import (
        "log"
        "os"
        "path/filepath"

        "github.com/judwhite/go-svc/svc"
)

// implements svc.Service
type program struct {
        LogFile *os.File
        svr     *server
}

func main() {
        prg := program{
                svr: &server{},
        }
        defer func() {
                if prg.LogFile != nil {
                        prg.LogFile.Close()
                }
        }()

        // call svc.Run to start your program/service
        // svc.Run will call Init, Start, and Stop
        if err := svc.Run(prg); err != nil {
                log.Fatal(err)
        }
}

func (p program) Init(env svc.Environment) error {
        log.Printf("is win service? %v\n", env.IsWindowsService())

        // write to "example.log" when running as a Windows Service
        if env.IsWindowsService() {
                dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
                if err != nil {
                        return err
                }

                logPath := filepath.Join(dir, "example.log")

                f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
                if err != nil {
                        return err
                }

                p.LogFile = f

                log.SetOutput(f)
        }

        return nil
}

func (p program) Start() error {
        log.Printf("Starting...\n")
        go p.svr.start()
        return nil
}

func (p program) Stop() error {
        log.Printf("Stopping...\n")
        if err := p.svr.stop(); err != nil {
                return err
        }
        log.Printf("Stopped.\n")
        return nil
}

package main

import (
        "log"
        "sync"
        "time"
)

type server struct {
        data chan int

        exit chan struct{}
        wg   sync.WaitGroup
}

func (s *server) start() {
        s.data = make(chan int)
        s.exit = make(chan struct{})

        s.wg.Add(2)
        go s.startSender()
        go s.startReceiver()
}

func (s *server) stop() error {
        close(s.exit)
        s.wg.Wait()
        return nil
}

func (s *server) startSender() {
        ticker := time.NewTicker(time.Second)
        count := 1
        for {
                select {
                case <-ticker.C:
                        s.data <- count
                        count++
                case <-s.exit:
                        s.wg.Done()
                        return
                }
        }
}

func (s *server) startReceiver() {
        for {
                select {
                case n := <-s.data:
                        log.Printf("%d\n", n)
                case <-s.exit:
                        s.wg.Done()
                        return
                }
        }
}