智能在线客服系统源码GOFLY开发日志-6. gin框架的优雅退出

开发好项目后,也能正常运行起来了,但是怎么退出才算优雅的退出呢。

一般情况下,执行命令行的前台进程,直接按ctrl+c进程就退出了,这不算是优雅的退出。网上的资料里,优雅退出gin进程,是需要处理下ctrl+c时候的进程信号,然后处理完所有请求在退出。

调用http实现优雅退出

我实现的是,通过调用一下http接口,就能触发进程退出,再配合上守护进程模式,子进程会被自动重启,相当于是重启服务了。也是在前面信号量的基础上修改了一点点,就实现了这个效果。

首先需要先修改下gin最后run方法那里,需要包装一下

    baseServer := "0.0.0.0:" + port
    engine := gin.Default()
    //engine.Run(baseServer)
    srv := &http.Server{
        Addr:    baseServer,
        Handler: engine,
    }

    go func() {
        if err := srv.ListenAndServe(); err != nil {
            log.Printf("GOFLY服务监听: %s\n", err)
        }
    }()

    <-controller.StopSign
    log.Println("关闭服务...")
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Fatal("服务关闭失败:", err)
    }
    log.Println("服务已关闭")

上面代码里,就是把监听方法的阻塞放在了一个groutine里,主groutine被<-stopSign这个读取通道的指令阻塞住。

然后在http路由里,往stopSign这个channel发消息,主groutine收到消息,就执行后面的关闭程序

systemGroup.GET("/stop", controller.GetStop)
package controller

import (
    "github.com/gin-gonic/gin"
)

var StopSign = make(chan int)

func GetStop(c *gin.Context) {

    StopSign <- 1

    c.JSON(200, gin.H{
        "code": 200,
        "msg":  "ok",
    })
}

后面还遇到了哪些问题和知识点将会继续进行总结。

演示网站:
gofly.sopans.com

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 2

可以把这个和之前的放在一个系列里面吗?

2年前 评论
程序员老狼 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!