Go的http包详解
Go的http包详解 详细地解剖一下 http 包,看它到底是怎样实现整个过程的。 Go 的 http 有两个核心功能:Conn、ServeMux Conn的goroputine 为了实现高并发和高性能,go使用了goroutine来处理Conn的读写事件,这样每个请求都能保持独立,相互不会阻塞,可以高效的相应网络事件。 go在等待客户端请求中是这样的: c, err := srv.newConn(rw) if err != nil { continue } go c.serve() 可以看到,客户端的每次请求都会创建一个Conn,这个Conn里面保存了该次请求的信息,然后再传递到相应的handler,该handler中便可以读取到相应的header信息,这样保证了每个请求的独立性。 ServeMux的自定义 conn.server内部调用了http包默认的路由器,通过路由器把本次请求的信息传递到了后端的处理函数,那么这个路由器是怎么实现的呢? 它的结构如下: type ServeMux struct{ mu sync.RWMutext // 锁,请求涉及到并发处理,因此需要一个锁机制 m map[string]muxEntry // 路由规则,一个String对应一个mux实体,这里的String就是注册的一个路由表达式 hosts bool // 是否在任意的规则中带有host信息 } 下面看一下muxEntry type muxEntry struct { explicit bool // 是否精确匹配 h Handler // 这个路由表达式对应哪个handler pattern string // 匹配字符串 } 在看一下Handler的定义 type Handler interface { ServeHTTP(ResponseWriter, *Request) // 路由实现器 } Handler是一个接口,但是附中的sayhelloName函数中并没有实现ServeHTTP这个接口,为什么能添加呢?这是因为http包里面还定义了一个类型HandlerFunc,定义的函数sayhelloName就是这个HandlerFunc调用之后的结果,这个类型默认就实现了ServeHTTP这个方法,即我们调用了HandlerFunc(f),强制类型转换f成为HandlerFunc类型,这样f就拥有了ServeHTTP方法。...