安全启动、优雅退出

在服务开发的时候,可能会遇到服务频繁启动或者频繁销毁的情况,需要分配和回收服务的资源;同时如果在服务关闭处理的不优雅的情况,还可能会丢失数据,因此服务设计的时候,需要考虑如何优雅的对服务进行启停。

 

package main

import (
    "fmt"
    "os"
    "os/signal"
    "sync"
    "syscall"
)

func main() {
    svr := MyService{}
    svr.Start()

    // 监听终止信号
    signalCh := make(chan os.Signal, 1)
    signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)

    // 等待接收终止信号
    <-signalCh

    svr.Stop()

    fmt.Println("Exiting program...")
    os.Exit(0)
}

type MyService struct {
    isOpen bool
    rwLock sync.RWMutex // 读共享,写排斥
    stop   int32
    once   sync.Once
}

func (s *MyService) Start() {
    s.rwLock.Lock()
    defer s.rwLock.Unlock()
    if s.isOpen {
        return
    }

    // 初始化资源

    s.isOpen = true
}

func (s *MyService) Stop() {
    s.once.Do(func() {
        // 获取写锁。如果有其他goroutine持有读锁或写锁,当前goroutine会阻塞直到获取到写锁为止
        s.rwLock.Lock()
        defer s.rwLock.Unlock()
        if !s.isOpen {
            return
        }

        // 释放资源

        s.isOpen = false
    })
}

func (s *MyService) Handle() {
    // 获取读锁。如果有其他goroutine持有写锁,当前goroutine会阻塞直到获取到读锁为止
    s.rwLock.RLock()
    defer s.rwLock.RUnlock()

    if !s.isOpen {
        return
    }
    // 业务处理
}

 

posted @ 2023-08-23 20:14  知道了呀~  阅读(13)  评论(0编辑  收藏  举报