braintree/manners实现web进程graceful退出

最近发现traefik和当前做的api gateway的请求处理流程极为相似,所以从traefik借鉴server开启/关闭等处理。最重要的是把gracefulServer的理念加到gateway中。

traefik利用github.com/braintree/manners做的graceful shutdown机制。

gracefule机制主要目的是,在拒绝新request的前提下,已经建立连接的请求需要处理完毕,再退出server。

http.Server在项目中的一般使用方法是,在goroutine中ListenAndServe,然后主进程中通过<-stopchan停住,这样可以通过stopchan停止主进程,来关闭掉server,如果直接ListenAndServe相当于只能通过该方法内置的信号量监听者停止服务。这种包装native pkg的方法在go中可能比较常见。

面对graceful第一次还是在阅读beego启动服务部分的代码,那时并没有关注这个问题,因为一个不重要的后台项目,不graceful又能怎样。

下面就来聊下manners中graceful的实现方法,要达到graceful,需要解决两个问题:

  • 当监听到signals时,首先要拒绝掉所有新请求的到来
  • 然后,处理掉所有pending的request,并退出

第一个机制manners通过gracefulHandler实现,这个struct包装了http.Handler并通过atomic包作为是否接收request的看门人

第二个机制manners通过监听http.ConnState来向sync.WaitGroup中注册pending的request实现,如果收到stop server的signal,就会触发wg.Wait()一直等待pending的request执行完毕

代码比较少,但比较实用,里面的test case也可能会给测试http主流程带来一些启发。

braintree/manners实现web进程graceful退出
Share this