关于java:Go语言HTTP服务生命周期

在 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)
    }
}

参考资料

  • how-to-stop-http-listenandserve
  • go-how-can-i-start-the-browser-after-the-server-started-listening

我是MonkeyWie,欢送扫码????????关注!不定期在公众号中分享JAVAGolang前端dockerk8s等干货常识。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理