os/signal 优雅退出

如果进程使用 SIGINT (shell 中的 Ctrl-C)或 SIGTERM (如 docker stop 或 kubernetes start)终止时,可以使用 signal.Notify 做一些收尾的工作,优雅退出go进程。

package main

import (
    "fmt"
    "math"
    "os"
    "os/signal"
    "syscall"
    "time"
)

var reader string

// listentSinnal 用于优雅退出
// 调用方式 go listentSinnal()
func listentSinnal() {
    c := make(chan os.Signal, 1)

    // 监听指定的系统信号,例如 SIGINT 和 SIGTERM,用于优雅退出
    signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
    // 阻塞等待信号,当接收到信号时,将信号值存入 sig 变量
    sig := <-c
    // 打印接收到的信号信息
    fmt.Printf("get message:%s \n", sig.String())

    // 检查 reader 是否为空,做相应的处理
    if reader == "" {
        fmt.Println("reader is empty")
    }

    // 退出程序,状态码为 0,表示正常退出
    os.Exit(0)
}

func main() {

    go listentSinnal()

    maxCount := math.MaxInt64
    fmt.Println(maxCount)
    maxConcurrent := 10 // 最大并发数为10

    ch := make(chan struct{}, maxConcurrent) // 创建一个容量为10的channel

    for i := 0; i < maxCount; i++ {
        ch <- struct{}{} // 在channel中放入一个空结构体
        go func(i int) {
            // 做一些各种各样的业务逻辑处理
            fmt.Printf("go func num: %d\n", i)
            time.Sleep(time.Second)
            <-ch // 从channel中取出一个空结构体
        }(i)
    }

}