- ListenAndServe執行流程如下圖,Go為了實現高并發和高性能, 使用了goroutines來處理Conn的讀寫事件, 這樣每個請求都能保持獨立,相互不會阻塞,可以高效的響應網絡事件。這是Go高效的保證。
一、ListenAndServe流程圖
3.3.illustrator.png
二、GoWeb詳細執行流程
- 首先調用
http.HandleFunc
,按順序做了幾件事:
- 調用了DefaultServeMux的HandleFunc
- 調用了DefaultServeMux的Handle
- 往DefaultServeMux的map[string]muxEntry中增加對應的handler和路由規則
- 其次調用
http.ListenAndServe(":9090", nil)
,按順序做了幾件事情:
- 實例化Server
- 調用Server的ListenAndServe()
- 調用
net.Listen("tcp", addr)
監聽端口 - 啟動一個for循環,在循環體中Accept請求
- 對每個請求實例化一個Conn,并且開啟一個goroutine為這個請求進行服務
go c.serve()
- 在中讀取每個請求的內容
w, err := c.readRequest()
- 判斷handler是否為空,如果沒有設置handler(這個例子就沒有設置handler),handler就設置為DefaultServeMux
- 調用handler的ServeHttp
- 在這個例子中,下面就進入到DefaultServeMux.ServeHttp
- 根據request選擇handler,并且進入到這個handler的ServeHTTP
mux.handler(r).ServeHTTP(w, r)
- 選擇handler:
A 判斷是否有路由能滿足這個request(循環遍歷ServerMux的muxEntry)
B 如果有路由滿足,調用這個路由handler的ServeHttp
C 如果沒有路由滿足,調用NotFoundHandler的ServeHttp