0. http包使用
因為後面的專案基本要從tcp或者http開始,所以這裡先介紹其機制
http.HandleFunc("/hello", helloHandler) #註冊預設服務邏輯上的路由請求
http.ListenAndServe(":8080", nil) #監聽指定埠,並使用預設服務
http.ListenAndServe(":8080", r) #監聽指定埠,並使用指定服務,也就是r結構需要實現相應函式以適應該介面
一. geeweb
首先是總的框架架構,複用net/http包,也就是基於http實現,不從底層報文協議上開始,而是業務開發框架
模組名稱 |
功能 |
main |
配置基礎路由和服務、註冊中間註冊分組路由函式、啟動對應埠服務 |
Engine |
服務實體,巢狀分組根節點,記錄路由根節點,記錄所有分組 |
RouterGroup |
分組實體、分組中介軟體、父分組、服務實體 |
Context |
請求和響應的實體,記錄上下文、該次請求中介軟體、解析和生成報文 |
router |
管理路由樹實體、用於註冊路由函式、最終執行實體 |
主體執行框架首先是初始化服務,以及註冊分組上的中介軟體、路由處理函式、接著監聽埠
全域性一個engine例項,若干group例項,前者管理監聽路口和所有分組以及路由樹根節點,後者用來註冊中介軟體和路由函式
使用http.ListenAndServe(addr, engine)
監聽埠,當請求到達,自動為請求建立新的http連線實體,
然後執行ServeHTTP(w http.ResponseWriter, req *http.Request)
,這裡都是使用新的協程接管,服務只需面向新協程處理完整的http報文
結構體 Engine
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
Engine |
結構體 |
*RouterGroup, *router, []*RouterGroup, *template.Template, template.FuncMap |
- |
Web 服務的核心引擎結構體,處理路由和模板 |
New() |
建構函式 |
- |
*Engine |
構造 Engine 例項 |
Default() |
建構函式 |
- |
*Engine |
建立預設的 Engine ,並註冊中介軟體 |
SetFuncMap() |
結構體函式 |
funcMap template.FuncMap |
- |
自定義模板渲染函式的對映 |
LoadHTMLGlob() |
結構體函式 |
pattern string |
- |
載入並解析指定的 HTML 模板檔案 |
Run() |
結構體函式 |
addr string |
error |
啟動 HTTP 伺服器,並監聽指定地址 |
ServeHTTP() |
結構體函式 |
w http.ResponseWriter, req *http.Request |
- |
實現 HTTP 請求的處理,應用中介軟體和路由 |
結構體 RouterGroup
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
RouterGroup |
結構體 |
prefix string, middlewares []HandlerFunc, parent *RouterGroup, engine *Engine |
- |
路由組,支援路由分組和中介軟體功能 |
Group() |
結構體函式 |
prefix string |
*RouterGroup |
建立新的路由組,所有組共享同一 Engine 例項 |
Use() |
結構體函式 |
middlewares ...HandlerFunc |
- |
向當前路由組新增中介軟體 |
addRoute() |
結構體函式 |
method, comp string, handler HandlerFunc |
- |
為當前路由組新增新的路由規則 |
GET() |
結構體函式 |
pattern string, handler HandlerFunc |
- |
新增 GET 請求的路由處理 |
POST() |
結構體函式 |
pattern string, handler HandlerFunc |
- |
新增 POST 請求的路由處理 |
createStaticHandler() |
結構體函式 |
relativePath string, fs http.FileSystem |
HandlerFunc |
建立處理靜態檔案請求的處理函式 |
Static() |
結構體函式 |
relativePath, root string |
- |
為靜態檔案建立路由 |
這裡將http的請求報文和響應報文封裝context實體,也就是一次請求對應一個context實體,context記錄這個報文需要使用的中介軟體(因為是巢狀分組所以要根據字首遍歷一遍獲取所有中介軟體)
結構體 Context
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
Context |
結構體 |
Writer http.ResponseWriter, Req *http.Request, Path, Method string, Params map[string]string, StatusCode int, handlers []HandlerFunc, index int, engine *Engine |
- |
儲存 HTTP 請求上下文,包含請求資訊、響應資訊以及處理流程 |
newContext() |
建構函式 |
w http.ResponseWriter, req *http.Request |
*Context |
建立並初始化 Context 例項 |
Next() |
結構體函式 |
- |
- |
呼叫下一個中介軟體或處理器函式 |
Fail() |
結構體函式 |
code int, err string |
- |
設定失敗狀態碼並返回錯誤資訊的 JSON 響應 |
Param() |
結構體函式 |
key string |
string |
獲取 URL 中的引數值 |
PostForm() |
結構體函式 |
key string |
string |
獲取 POST 表單中的引數 |
Query() |
結構體函式 |
key string |
string |
獲取 URL 查詢字串中的引數 |
Status() |
結構體函式 |
code int |
- |
設定 HTTP 響應狀態碼 |
SetHeader() |
結構體函式 |
key, value string |
- |
設定 HTTP 響應頭 |
String() |
結構體函式 |
code int, format string, values ...interface{} |
- |
返回文字響應 |
JSON() |
結構體函式 |
code int, obj interface{} |
- |
返回 JSON 格式的響應 |
Data() |
結構體函式 |
code int, data []byte |
- |
返回原始位元組資料 |
HTML() |
結構體函式 |
code int, name string, data interface{} |
- |
返回 HTML 響應,使用模板渲染 |
router管理路由樹,路由函式的註冊以及最終的鏈式執行
結構體 router
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
router |
結構體 |
roots map[string]*node, handlers map[string]HandlerFunc |
- |
路由結構,儲存不同 HTTP 方法的路由樹和處理函式 |
newRouter() |
建構函式 |
- |
*router |
構造 router 例項 |
parsePattern() |
函式 |
pattern string |
[]string |
將路由路徑分割為部分,解析路徑中的引數和萬用字元 |
addRoute() |
結構體函式 |
method, pattern string, handler HandlerFunc |
- |
向路由樹中新增新的路由及其處理函式 |
getRoute() |
結構體函式 |
method, path string |
*node, map[string]string |
根據請求的方法和路徑,匹配對應的路由節點和引數 |
getRoutes() |
結構體函式 |
method string |
[]*node |
獲取某一 HTTP 方法下的所有路由節點 |
handle() |
結構體函式 |
c *Context |
- |
處理 HTTP 請求,根據路由匹配並執行相應處理函式 |
router採用的字首樹結構
結構體 node
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
node |
結構體 |
pattern string, part string, children []*node, isWild bool |
- |
路由樹節點,用於表示路由規則中的某一部分 |
String() |
結構體函式 |
- |
string |
返回當前節點的字串表示形式 |
insert() |
結構體函式 |
pattern string, parts []string, height int |
- |
向路由樹中插入一個新節點 |
search() |
結構體函式 |
parts []string, height int |
*node |
在路由樹中搜尋與給定路徑匹配的節點 |
travel() |
結構體函式 |
list *([]*node) |
- |
遍歷當前節點及其子節點,並將匹配的節點新增到列表中 |
matchChild() |
結構體函式 |
part string |
*node |
查詢匹配當前部分的子節點 |
matchChildren() |
結構體函式 |
part string |
[]*node |
查詢匹配當前部分的所有子節點 |
二. gee-cache
首先還是從主函式看起,啟動三個分散式快取服務程序(各自會在程序內新建一個group管理快取),以及一個對外的http服務測試執行緒
當http請求到達,也就是查詢一個key值,呼叫對應group的查詢值函式
模組名稱 |
功能 |
main |
初始化監聽、初始化三個快取實體和三個分散式快取監聽服務 |
Group |
單個快取實體,用於管理LRU快取結構和註冊預設硬碟查詢函式 |
Map |
一致性雜湊,用於註冊獲取遠端服務 |
HTTPPool |
快取服務監聽和請求實體,服務遠端請求和申請遠端請求 |
cache |
快取結構實體 |
group查詢值的時候,首先查詢本地LRU快取,如果有直接返回
如果沒有,先根據key找一個遠端服務節點
結構體 Group
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
Group |
結構體 |
name string, getter Getter, mainCache cache, peers PeerPicker, loader *singleflight.Group |
- |
快取名稱空間及其關聯資料,負責管理本地快取和遠端節點互動 |
NewGroup() |
建構函式 |
name string, cacheBytes int64, getter Getter |
*Group |
建立一個新的 Group 例項,用於管理快取資料 |
GetGroup() |
函式 |
name string |
*Group |
根據名稱返回已建立的 Group 例項,如果沒有則返回 nil |
Get() |
結構體函式 |
key string |
ByteView, error |
根據鍵值從快取中獲取資料,如果快取不存在則載入資料 |
RegisterPeers() |
結構體函式 |
peers PeerPicker |
- |
註冊遠端節點選擇器,用於分散式快取的節點選擇 |
load() |
結構體函式 |
key string |
ByteView, error |
載入指定鍵的快取資料,支援遠端節點獲取或本地載入 |
populateCache() |
結構體函式 |
key string, value ByteView |
- |
將載入的值新增到本地快取中 |
getLocally() |
結構體函式 |
key string |
ByteView, error |
從本地獲取資料,透過 getter 載入並快取 |
getFromPeer() |
結構體函式 |
peer PeerGetter, key string |
ByteView, error |
從遠端節點獲取資料,並返回對應的快取值 |
這裡是使用一致性雜湊獲取對應的遠端服務地址,同時對於大量相同的key的呼叫,會使用map對映一個call進行阻塞,其它相同key請求等待第一個call完畢
執行一個整合的http遠端請求,獲取得到值
結構體 Map
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
Map |
結構體 |
hash Hash, replicas int, keys []int, hashMap map[int]string |
- |
用於一致性雜湊儲存的結構體,管理雜湊環上的所有鍵 |
New() |
建構函式 |
replicas int, fn Hash |
*Map |
建立一個 Map 例項,用於一致性雜湊 |
Add() |
結構體函式 |
keys ...string |
- |
向雜湊環中新增節點,並生成副本 |
Get() |
結構體函式 |
key string |
string |
根據提供的鍵值查詢雜湊環上最接近的節點 |
使用遠端請求key的方法,會自動根據註冊的遠端服務地址以及對應的方法獲取遠端地址,同時呼叫http遠端請求直到獲取返回值
結構體 HTTPPool
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
HTTPPool |
結構體 |
self string, basePath string, mu sync.Mutex, peers *consistenthash.Map, httpGetters map[string]*httpGetter |
- |
管理 HTTP 節點的連線池,用於與分散式快取中的其他節點互動 |
NewHTTPPool() |
建構函式 |
self string |
*HTTPPool |
初始化一個新的 HTTPPool ,用於管理節點間的通訊 |
Log() |
結構體函式 |
format string, v ...interface{} |
- |
列印日誌資訊,包含節點名 |
ServeHTTP() |
結構體函式 |
w http.ResponseWriter, r *http.Request |
- |
處理 HTTP 請求,並根據路徑獲取快取資料 |
Set() |
結構體函式 |
peers ...string |
- |
更新節點池中的 peers 列表,併為每個節點初始化 httpGetter |
PickPeer() |
結構體函式 |
key string |
PeerGetter, bool |
根據鍵值選擇適合的節點進行請求 |
結構體 httpGetter
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
httpGetter |
結構體 |
baseURL string |
- |
HTTP 客戶端,用於從遠端節點獲取快取資料 |
Get() |
結構體函式 |
in *pb.Request, out *pb.Response |
error |
從遠端節點獲取快取資料,並將其解碼為響應 |
結構體 Cache
及其關聯函式
結構體/函式名 |
型別 |
引數 |
返回值 |
功能描述 |
Cache |
結構體 |
maxBytes int64, nbytes int64, ll *list.List, cache map[string]*list.Element, OnEvicted func(key string, value Value) |
- |
LRU 快取的主要結構體,管理快取項、容量、元素淘汰等功能 |
New() |
建構函式 |
maxBytes int64, onEvicted func(string, Value) |
*Cache |
建立一個 Cache 例項,初始化快取引數和淘汰函式 |
Add() |
結構體函式 |
key string, value Value |
- |
新增或更新快取項,並根據快取大小判斷是否淘汰最舊的元素 |
Get() |
結構體函式 |
key string |
Value, bool |
根據鍵值查詢快取項,如果存在則返回,並將該項移動到最前面 |
RemoveOldest() |
結構體函式 |
- |
- |
移除快取中最舊的元素(LRU 策略),並呼叫淘汰函式 |
Len() |
結構體函式 |
- |
int |
返回快取中當前儲存的條目數量 |
三. gee-rpc
從main視角,首先初始化服務註冊中心
註冊中心監聽服務請求埠,基於http進行響應,對請求方GET返回服務例項,對服務端POST的心跳機制進行更新