1、背景
运行一个http服务通常需要两步,第一步是注册路由,第二步是启动服务。当我们发送一个http请求时,启动服务内部会处理我们的请求,通过路由匹配找到对应的回调函数来执行,有的业务场景可能需要路由对应的整个回调函数因为某种情况整个逻辑都变化,接下来我们就来提供一种更新路由对应的回调函数的示例。
2、gin框架下载
go get -u github.com/gin-gonic/gin
3、代码示例
【1】定义可动态更新的http处理器
//用于动态更新回调函数
type DynamicHandler struct {
handler http.Handler //http处理器
lock sync.RWMutex //保证更新http处理器接口时的并发安全
}
//处理http请求
func (d *DynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
d.lock.RLock()
defer d.lock.RUnlock()
d.handler.ServeHTTP(w, r) //真正处理http请求的地方
}
func (d *DynamicHandler) Update(h http.Handler) {
d.lock.Lock()
defer d.lock.Unlock()
d.handler = h //更新http处理器
}
【2】定义初始化和更新的回调函数
//初始化的回调函数
func initialHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(fmt.Sprintf("init time:%s", time.Now().Format("2006-01-02 15:04:05"))))
})
}
//更新之后的回调函数
func newHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(fmt.Sprintf("udpate time:%s", time.Now().Format("2006-01-02 15:04:05"))))
})
}
【3】使用方法
func main() {
r := gin.New()
//初始化回调函数
dh := &DynamicHandler{handler: initialHandler()}
r.GET("/xxx", func(c *gin.Context) {
dh.ServeHTTP(c.Writer, c.Request)
})
go func() {
time.Sleep(60 * time.Second)
//60秒之后更新回调函数
dh.Update(newHandler())
}()
r.Run(":9999")
}
运行服务端程序之后,手动curl一下接口控制台输出:
$ curl http://127.0.0.1:9999/xxx
init time:2025-05-09 14:54:03
60秒之后再次手动curl一下控制台输出:
$ curl http://127.0.0.1:9999/xxx
udpate time:2025-05-09 14:55:20