23

Go语言HTTP服务生命周期

 3 years ago
source link: https://studygolang.com/articles/31233
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在 go 语言里启动一个 http 服务非常简单,只需要一行代码 http.ListenAndServe() 就可以搞定,这个方法会一直阻塞着直到进程关闭,如果这个时候来了些特殊的需求比如:

  • 监听服务启动
  • 手动关闭服务
  • 监听服务关闭

在 go 中应该怎么实现呢?下面来一一举例。

监听服务启动

方法一(推荐)

Listen 步骤拆分出来,先监听端口,再绑定到 server 上,代码示例:

l, _ := net.Listen("tcp", ":8080")
// 服务启动成功,进行初始化
doInit()
// 绑定到server上
http.Serve(l, nil)

方法二

通过一个 协程 去轮询监听服务启动状态,代码示例:

go func() {
    for {
        if _, err := net.Dial("tcp", "127.0.0.1:8080"); err == nil {
            // 服务启动成功,进行初始化
            doInit()
            //退出协程
            break
        }
        // 每隔一秒检查一次服务是否启动成功
        time.Sleep(time.Second)
    }
}()
http.ListenAndServe(":8080", nil)

手动关闭服务

优雅关闭(推荐)

http 包中并没有暴露服务的关闭方法,通过 http.ListenAndServe() 方法启动的 http 服务默认帮我们创建了一个 *http.Server 对象,源码如下:

func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}

实际上在 *http.Server 中是有提供 Shutdown 方法的,所以我们只需要手动构造一个 *http.Server 对象,就可以进行优雅关闭了,代码示例:

srv := &http.Server{Addr: ":8080"}
go func(){
    // 10秒之后关闭服务
    time.Sleep(time.Second * 10)
    srv.Shutdown(context.TODO())
}()
// 启动服务
srv.ListenAndServe()

强制关闭

强制关闭和上面步骤是一样的,只是调用的方法换成了 srv.Close() ,这会导致所有的请求立即中断,所以需要特别注意。

监听服务关闭

当我们手动将服务关闭之后, srv.ListenAndServe() 方法就会立即返回,这里需要注意的是该方法会返回一个 error ,当然这个 error 是一个特殊的 error http.ErrServerClosed ,帮助我们区分是否为正常的服务关闭,所以需要对它特殊处理下,代码示例:

if err := server.ListenAndServe(); err != nil {
    // 服务关闭,进行处理
    doShutdown()
    if err != http.ErrServerClosed{
        // 异常宕机,打印错误信息
        log.Fatal(err)
    }
}

参考资料

本文首发于我的博客: https://monkeywie.cn ,欢迎收藏!不定期分享 JAVAGolang前端dockerk8s 等干货知识。

有疑问加站长微信联系

iiUfA3j.png!mobile

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK