Go nethttp 学习笔记中,如何高效构建SEO策略?
摘要:概述 在使用 Go 开发时几乎都会用到 nethttp 标准库。但是,对库的内部实现不了解,仅限于会用。遇到问题容易懵,比如: 长连接和短连接有什么区别?具体什么实现原理? nethttp 如何处理并发请求? nethttp 有用到缓
概述
在使用 Go 开发时几乎都会用到 net/http 标准库。但是,对库的内部实现不了解,仅限于会用。遇到问题容易懵,比如:
长连接和短连接有什么区别?具体什么实现原理?
net/http 如何处理并发请求?
net/http 有用到缓存吗?缓存用来干什么?
......
单个问题各个击破,不如深入梳理下 net/http 标准库一网打尽。本文将深入学习 net/http 标准库,力图做到知其然知其所以然。
服务端
源码走读
先看一段服务端示例代码:
func helloHandler(w http.ResponseWriter, r *http.Request) {
// 向客户端写入响应内容
fmt.Fprint(w, "Hello I am server 3")
}
func main() {
// 创建自定义的ServeMux实例
mux := http.NewServeMux()
// 在mux上注册路由和处理函数
mux.HandleFunc("/", helloHandler)
// 启动服务器并监听12302端口,使用自定义的mux作为handler
fmt.Println("Server is listening on port 12302...")
if err := http.ListenAndServe(":12302", mux); err != nil {
// 错误处理
fmt.Printf("Failed to start server: %v\n", err)
}
}
示例中有几类概念需要介绍。
多路复用器 http.ServeMux
type ServeMux struct {
mu sync.RWMutex // 多路复用器锁
tree routingNode // 路由节点,用来存储路由 pattern 和对应的 handler
...
}
路由处理器 handler
handler 是一个实现 func(ResponseWriter, *Request) 函数接口的函数,用来处理请求。
流程
服务端启动需要经过以下流程。
1) 创建多路复用器
创建自定义 http.ServeMux 多路复用器,如果不创建的话,则会使用默认 http.DefaultServeMux 多路复用器:
// NewServeMux allocates and returns a new [ServeMux].
func NewServeMux() *ServeMux {
return &ServeMux{}
}
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
2) 注册路由处理器
调用多路复用器的 HandleFunc 方法注册路由处理器:
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if use121 {
mux.mux121.handleFunc(pattern, handler)
} else {
// 将 pattern 和路由处理器注册到多路复用器
mux.register(pattern, HandlerFunc(handler))
}
}
注册的过程实际是将 pattern 和 handler 的映射关系写入 ServeMux.tree 中。可以根据请求的 pattern 从 ServeMux.tree 中获取对应的 handler。
