在 go 语言里启动一个 http 服务非常简单,只需要一行代码http.ListenAndServe()
就可以搞定,这个方法会一直阻塞着直到进程关闭,如果这个时候来了些特殊的需求比如:
- 监听服务启动
- 手动关闭服务
- 监听服务关闭
在 go 中应该怎么实现呢?下面来一一举例。
监听服务启动
方法一(推荐)
将Listen
步骤拆分出来,先监听端口,再绑定到server
上,代码示例:
1 | l, _ := net.Listen("tcp", ":8080") |
方法二
通过一个协程
去轮询监听服务启动状态,代码示例:
1 | go func() { |
手动关闭服务
优雅关闭(推荐)
在http
包中并没有暴露服务的关闭方法,通过http.ListenAndServe()
方法启动的 http 服务默认帮我们创建了一个*http.Server
对象,源码如下:
1 | func ListenAndServe(addr string, handler Handler) error { |
实际上在*http.Server
中是有提供Shutdown
方法的,所以我们只需要手动构造一个*http.Server
对象,就可以进行优雅关闭了,代码示例:
1 | srv := &http.Server{Addr: ":8080"} |
强制关闭
强制关闭和上面步骤是一样的,只是调用的方法换成了srv.Close()
,这会导致所有的请求立即中断,所以需要特别注意。
监听服务关闭
当我们手动将服务关闭之后,srv.ListenAndServe()
方法就会立即返回,这里需要注意的是该方法会返回一个error
,当然这个error
是一个特殊的 error http.ErrServerClosed
,帮助我们区分是否为正常的服务关闭,所以需要对它特殊处理下,代码示例:
1 | if err := server.ListenAndServe(); err != nil { |