這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
文章來源:http://gf.johng.cn/494375
gf架構提供了自建的非常強大的路由控制功能,支援流行的命名匹配規則及模糊比對規則,並提供了優秀的優先順序管理機制。以下是一個服務註冊中使用路由控制的樣本:
package mainimport "gitee.com/johng/gf/g/net/ghttp"func main() { s := ghttp.GetServer() s.BindHandler("/:name", func(r *ghttp.Request){ r.Response.Writeln("pattern: /:name match") r.Response.Writeln(r.Get("name")) }) s.BindHandler("/:name/:action", func(r *ghttp.Request){ r.Response.Writeln("pattern: /:name/:action match") r.Response.Writeln(r.Get("name")) r.Response.Writeln(r.Get("action")) }) s.BindHandler("/:name/*any", func(r *ghttp.Request){ r.Response.Writeln("pattern: /:name/*any match") r.Response.Writeln(r.Get("name")) r.Response.Writeln(r.Get("any")) }) s.SetPort(8199) s.Run()}
其中,/:name/:action
的路由規則優先順序比/:name/*any
高,因此當訪問 http://127.0.0.1:8199/john/info
時,得到的結果是:
pattern: /:name/:action matchjohninfo
路由規則分為兩種:靜態路由規則 和 動態路由規則。
靜態路由規則
靜態路由規則是指不帶任何命名匹配和模糊比對的路由規則,即是一個確定的URI地址,例如:/user/info
,/src/path/file
,/member/register
等等。靜態路由規則在服務註冊及服務檢索的時候效率非常高,因為不需要做額外的優先順序和正則規則判斷,底層的資料結構僅僅是一張雜湊表,註冊和檢索的時間複雜度都為O(1)。因此,在實際項目開發中,建議能夠使用靜態路由規則的地方盡量使用靜態路由規則。
動態路由規則
動態路由規則分為兩種:命名匹配規則和模糊比對規則。動態路由的底層資料結構由樹形雜湊表和葉子節點的鏈表構成,樹形雜湊表便於高效率地層級匹配URI;葉子節點的鏈表用於優先順序控制,同一層級的路由規則按照優先順序進行排序,優先順序高的規則排在鏈表頭。底層的路由規則與請求URI的匹配計算採用的是Regex,並充分使用了緩衝機制,執行效率十分高效。
命名匹配規則
使用:name
方式進行匹配(name
為自訂的匹配名稱),對URI指定層級的參數進行命名匹配(類似正則([\w\.\-]+)
),對應匹配參數會被解析為GET參數並傳遞給註冊的服務使用。
匹配樣本1:
rule: /user/:user/user/john match/user/you match/user/john/profile no match/user/ no match
匹配樣本2:
rule: /:name/action/john/name no match/john/action match/smith/info no match/smith/info/age no match/smith/action match
匹配樣本3:
rule: /:name/:action/john/name match/john/info match/smith/info match/smith/info/age no match/smith/action/del no match
模糊比對規則
使用*any
方式進行匹配(any
為自訂的匹配名稱),對URI指定位置之後的參數進行模糊比對(類似正則(.*)
),並將匹配參數解析為GET參數並傳遞給註冊的服務使用。
匹配樣本1:
rule: /src/*path/src/ match/src/somefile.go match/src/subdir/somefile.go match/user/ no match/user/john no match
匹配樣本2:
rule: /src/*path/:action/src/ no match/src/somefile.go no match/src/somefile.go/del match/src/subdir/file.go/del match
匹配樣本3:
rule: /src/*path/show/src/ no match/src/somefile.go no match/src/somefile.go/del no match/src/somefile.go/show match/src/subdir/file.go/show match
路由優先順序控制
優先順序控制最主要的兩點因素:
- 層級越深的規則優先順序越高;
- 命名匹配比模糊比對優先順序高;
我們來看樣本(左邊的規則優先順序比右邊高):
/:name > /*any/user/name > /user/:action/:name/info > /:name/:action/:name/:action > /:name/*action/src/path/del > /src/path/src/path/del > /src/path/:action/src/path/*any > /src/path
本章節開頭的樣本中已經能夠很好的說明優先順序控制,這裡便不再舉例。
此外,需要說明的是,靜態匹配規則/
是比較特殊的一個規則,優先順序最低,當任何其他規則無法匹配時,會自動匹配到該規則下面,可以把它看做一個全域規則。例如,當系統有三條路由規則/
、/user
、/:name
,當應用端請求/user/register
時,將會被路由規則/
捕獲;當應用端請求/user
時,將會被路由規則/user
捕獲;當應用端請求/src
時,將會被路由規則/:name
捕獲。