很多人上来就用 Gin 或者 Echo,但其实标准库的 net/http 已经够用了。理解底层之后再用框架,出了问题才知道往哪查。
最简单的服务
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello")
})
http.ListenAndServe(":8080", nil)
}
跑起来之后 curl localhost:8080 就能看到响应。
Router 和中间件
http.ServeMux 是标准库内置的路由,Go 1.22 之后支持方法和路径参数了:
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", getUser)
mux.HandleFunc("POST /users", createUser)
中间件就是一个包裹 http.Handler 的函数,没什么神秘的:
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
优雅退出
生产环境必须处理 SIGTERM,否则重启时正在处理的请求会被直接切断:
srv := &http.Server{Addr: ":8080", Handler: mux}
go srv.ListenAndServe()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
srv.Shutdown(ctx)
← 返回