本文涉及以下两个库
"github.com/fvbock/endless"
"github.com/gin-gonic/gin"
gin为我们熟知的WEB封装框架,它是http中handle的实现:
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 设置HTTP服务器的超时时间为5秒
server := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
}
r.GET("/hello", func(c *gin.Context) {
time.Sleep(10 * time.Second) // 模拟耗时操作
c.String(http.StatusOK, "Hello, World!")
})
server.ListenAndServe()
}
gin框架中并没有对 ReadTimeout
与 WriteTimeout
的控制,它默认启动时,这两个参数都为0既不请求超时也不限制响应超时。 以下实现了一个简易的http常链接,可以通过curl http://127.0.0.1/stream
进行测试,也可以在浏览器直接访问 http://127.0.0.1/stream`
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
func main() {
r := gin.Default()
r.GET("/stream", func(c *gin.Context) {
c.Header("Content-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache")
c.Header("Connection", "keep-alive")
c.Header("Access-Control-Allow-Origin", "*")
messageChan := make(chan string)
go func() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
messageChan <- "This is a message"
}
}
}()
var i int
for {
i++
message := <-messageChan
fmt.Fprintf(c.Writer, "data: %d.%s\n\n", i,message)
c.Writer.Flush()
}
})
r.Run(":8080")
}
那么,上面的代码有一个问题,当代码有更新,需要重启时,如何优雅的的重启服务呢?endless
配合gin可以实现一个优雅的服务重启。
原理介绍:https://github.com/fvbock/endless/blob/master/examples/README.md
package main
import (
"fmt"
"github.com/fvbock/endless"
"github.com/gin-gonic/gin"
"time"
)
func main() {
r := gin.Default()
r.GET("/stream", func(c *gin.Context) {
c.Header("Content-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache")
c.Header("Connection", "keep-alive")
c.Header("Access-Control-Allow-Origin", "*")
messageChan := make(chan string)
go func() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
messageChan <- "This is a message"
}
}
}()
var i int
for {
i++
message := <-messageChan
fmt.Fprintf(c.Writer, "data: %d.%s\n\n", i,message)
c.Writer.Flush()
}
})
s := endless.NewServer(":8080", r)
s.ReadHeaderTimeout = 0
s.WriteTimeout = 0
s.MaxHeaderBytes = 1 << 20
_ = s.ListenAndServe()
}