Golang如何创建HTTP服务器_Golang net/http使用详解

8次阅读

使用 http.ListenAndServe 启动服务器时需手动 recover panic,优先用自定义 ServeMux 替代 DefaultServeMux,读取请求体前设 context 超时,上传限流用 MaxBytesReader,返回 jsON 必须显式设置 Content-Type。

Golang如何创建HTTP服务器_Golang net/http使用详解

http.ListenAndServe 启动最简服务器,但默认不处理 panic

直接调用 http.ListenAndServe(":8080", nil) 就能跑起一个 HTTP 服务,nil 表示使用默认的 http.DefaultServeMux。但要注意:如果 handler 函数里发生 panic,整个服务器会崩溃退出,没有任何恢复机制。生产环境必须自己包装 handler,用 recover() 捕获异常。

注册路由别只靠 http.HandleFunc,优先用自定义 http.ServeMux

http.HandleFunc 看似方便,但它往全局的 DefaultServeMux 注册,多个包之间容易冲突,也不利于测试和隔离。更可控的方式是显式创建 mux:

mux := http.NewServeMux() mux.HandleFunc("/api/users", usersHandler) mux.HandleFunc("/health", healthHandler) http.ListenAndServe(":8080", mux)
  • 每个服务实例可拥有独立 mux,避免隐式共享
  • 便于在测试中传入 mock mux 或替换 handler
  • 支持嵌套路由前缀:http.StripPrefix("/v1", mux)

处理请求体前务必设超时,否则 req.Body.Read 可能永久阻塞

HTTP 请求体(尤其是 POST/PUT)读取没有内置超时,客户端若只发 header 不发 body,req.Body.Read 会一直等下去。正确做法是在读取前设置上下文超时:

ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() r = r.WithContext(ctx)  body, err := io.ReadAll(r.Body) if err != nil {     // 可能是 context.DeadlineExceeded }
  • 不要依赖 http.Server.ReadTimeout(已弃用),它只管连接建立阶段
  • http.Server.ReadHeaderTimeouthttp.Server.IdleTimeout 才是现代替代项
  • 上传大文件时,建议配合 http.MaxBytesReader 限流

返回 json 别忘了设 Content-Type: application/json

很多人只写 json.NewEncoder(w).Encode(data),但浏览器前端 SDK 可能因缺失 Content-Type 头而解析失败。必须手动设置:

立即学习go语言免费学习笔记(深入)”;

w.Header().Set("Content-Type", "application/json; charset=utf-8") json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
  • 如果用了 http.Error,它不会自动设 Content-Type,错误响应也要自己补
  • 对非 UTF-8 字符(比如 GBK),需显式声明 charset;纯 ASCII 场景可省略 charset 部分
  • 中间件里统一设置 header 更安全,避免每个 handler 都重复写

golang 的 net/http 接口看似简单,但超时控制、panic 恢复、header 设置这些点,一旦漏掉就容易在线上出隐蔽问题。尤其在微服务间调用或公网暴露时,每个 handler 的健壮性都得单独验证。

text=ZqhQzanResources