作者:施洪寶
一. 介紹
-
1.codis使用了go中martini這個web框架
- martinie github地址: https://github.com/go-martini...
- 2.martini主要是利用go標準庫中的net包以及net/http包
二. net包
-
1.net包文檔
- 2.官方文檔中已經說明了如何使用net包實現tcp服務端監聽
ln, err := net.Listen("tcp", ":8080")
if err != nil {
// handle error
}
for {
conn, err := ln.Accept()
if err != nil {
// handle error
}
go handleConnection(conn)
}
- 從使用庫的一方來看, 接受連接的操作是阻塞式的, 使用方只需按照阻塞式網絡編程進行處理即可
- 由於go有自己的協程調度, 在接受網絡連接時, 實際使用的是IO多路複用, 具體則是通過sysmon線程進行操作
- 由於go具有垃圾自動回收以及協程, 故而針對每個網絡請求, 開啓單獨協程進行處理
三. net/http包
-
對於http服務, go提供了net/http包可以直接使用
-
使用示例(net/http包中還有其他方式構建http服務, 具體情況參考官方文檔)
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
- http.Handle, http.HandleFunc用於向DefaultServeMux註冊處理函數
- http.ListenAndServe用於啓動http服務, 當第二個參數爲nil時, 表示使用默認的DefaultServeMux處理http請求
3.1 源碼簡介
- 1.go採用1.11.4, 不同的版本實現可能不同, 源碼參見src/net/http/server.go
- 2.結構體定義
type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
hosts bool // whether any patterns contain hostnames
}
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
//http請求處理接口
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
- 3.函數定義
func Handle(pattern string, handler Handler)
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func ListenAndServe(addr string, handler Handler) error
-
4.基本流程
- 通過http.Handle或者http.HandleFunc, 向DefaultServeMux中註冊一些url相關的處理函數
- 通過http.ListenAndServe啓動web服務
- 客戶端發送http請求後, 服務端接受請求, 創建協程處理請求(找到最匹配的url並調用之前設置的處理函數)