Go 语言内置了功能强大的 net/http
包,用于构建 高性能 HTTP 服务 和 客户端请求。这是 Go 成为服务端开发热门语言的核心原因之一。
本文从背景、服务端开发、客户端请求、处理常见需求等多个方面 系统讲解 Go HTTP 的相关知识与实际用法
📌 一、背景介绍:Go HTTP 是什么?
Go 的 net/http
是标准库的一部分,包含:
模块 |
说明 |
http.Server |
用于创建 Web 服务器 |
http.Handler |
接口,处理 HTTP 请求 |
http.Client |
发起 HTTP 请求 |
http.Request |
客户端请求的信息封装 |
http.ResponseWriter |
服务端写入响应的接口 |
特性:
- 开箱即用,不依赖第三方框架
- 支持中间件、自定义路由
- 支持并发请求(默认支持)
- 可配合
context
实现超时控制、取消等高级功能
🚀 二、服务端开发:快速搭建一个 HTTP 服务器
✅ 示例:创建一个基本 HTTP 服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import ( "fmt" "net/http" )
func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, Go HTTP!") }
func main() { http.HandleFunc("/", helloHandler) fmt.Println("Listening on :8080") http.ListenAndServe(":8080", nil) }
|
📘 说明:
HandleFunc
将 URL 路径 /
绑定到处理函数
http.ListenAndServe
启动服务器并监听端口
- 每一个请求都会在 goroutine 中处理(自动并发)
🔄 三、自定义路由与多路径处理
1 2 3 4 5 6 7 8 9
| func aboutHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "This is the about page.") }
func main() { http.HandleFunc("/", helloHandler) http.HandleFunc("/about", aboutHandler) http.ListenAndServe(":8080", nil) }
|
🧱 四、自定义 http.Handler
实现更复杂逻辑
1 2 3 4 5 6 7 8 9 10 11 12
| type myHandler struct{}
func (h myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Handled by custom handler: %s\n", r.URL.Path) }
func main() { handler := myHandler{} http.ListenAndServe(":8080", handler) }
|
🧰 五、中间件机制(Logging、Auth 等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func logger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Printf("Received request: %s\n", r.URL.Path) next.ServeHTTP(w, r) }) }
func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello with middleware!") }
func main() { mux := http.NewServeMux() mux.HandleFunc("/", hello) http.ListenAndServe(":8080", logger(mux)) }
|
🌐 六、HTTP 客户端请求(GET/POST)
✅ GET 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package main
import ( "fmt" "io" "log" "net/http" )
func main() { resp, err := http.Get("https://httpbin.org/get") if err != nil { log.Fatal(err) } defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) }
|
✅ POST 请求
1 2 3 4 5
| resp, err := http.Post("https://httpbin.org/post", "application/json", bytes.NewBuffer([]byte(`{"name":"go"}`))) if err != nil { log.Fatal(err) } defer resp.Body.Close()
|
⏱ 七、结合 context 处理超时与取消
1 2 3 4 5 6 7 8 9 10 11 12 13
| func slowHandler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() fmt.Println("Handler started") defer fmt.Println("Handler ended")
select { case <-time.After(5 * time.Second): fmt.Fprintln(w, "Finished work") case <-ctx.Done(): http.Error(w, "Request canceled", http.StatusRequestTimeout) } }
|
🔒 八、生产场景推荐配置(含超时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func main() { srv := &http.Server{ Addr: ":8080", Handler: http.DefaultServeMux, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: 15 * time.Second, }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello with timeout!") })
log.Fatal(srv.ListenAndServe()) }
|
✅ 九、实际开发中 HTTP 最佳实践
实践 |
说明 |
✅ 路由封装 |
使用 ServeMux 或第三方框架如 chi 、gorilla/mux |
✅ 中间件设计 |
封装日志、认证、限流等 |
✅ context 控制 |
控制取消、超时(防止内存泄露) |
✅ 合理使用缓存 |
设置 Cache-Control 头、ETag |
✅ 日志记录 |
打印响应耗时、状态码等 |
✅ 优雅关闭 |
使用 context 和 os/signal 优雅退出 |