精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go-Zero 是如何做路由管理的?

開發 前端
對于 Web 框架來說,路由管理是必不可少的一部分,那么本文就來探討一下 go-zero 的路由管理是怎么做的,具體采用了哪種技術方案。

go-zero 是一個微服務框架,包含了 web 和 rpc 兩大部分。

而對于 web 框架來說,路由管理是必不可少的一部分,那么本文就來探討一下 go-zero 的路由管理是怎么做的,具體采用了哪種技術方案。

路由管理方案

路由管理方案有很多種,具體應該如何選擇,應該根據使用場景,以及實現的難易程度做綜合分析,下面介紹常見的三種方案。

注意這里只是做一個簡單的概括性對比。

標準庫方案

最簡單的方案就是直接使用 map[string]func() 作為路由的數據結構,鍵為具體的路由,值為具體的處理方法。

// 路由管理數據結構

type ServeMux struct {
    mu    sync.RWMutex          // 對象操作讀寫鎖
    m     map[string]muxEntry   // 存儲路由映射關系
}

這種方案優點就是實現簡單,性能較高;缺點也很明顯,占用內存更高,更重要的是不夠靈活。

Trie Tree

Trie Tree 也稱為字典樹或前綴樹,是一種用于高效存儲和檢索、用于從某個集合中查到某個特定 key 的數據結構。

圖片

Trie Tree 時間復雜度低,和一般的樹形數據結構相比,Trie Tree 擁有更快的前綴搜索和查詢性能。

和查詢時間復雜度為 O(1) 常數的哈希算法相比,Trie Tree 支持前綴搜索,并且可以節省哈希函數的計算開銷和避免哈希值碰撞的情況。

最后,Trie Tree 還支持對關鍵字進行字典排序。

Radix Tree

Radix Tree(基數樹)是一種特殊的數據結構,用于高效地存儲和搜索字符串鍵值對,它是一種基于前綴的樹狀結構,通過將相同前綴的鍵值對合并在一起來減少存儲空間的使用。

圖片

Radix Tree 通過合并公共前綴來降低存儲空間的開銷,避免了 Trie Tree 字符串過長和字符集過大時導致的存儲空間過多問題,同時公共前綴優化了路徑層數,提升了插入、查詢、刪除等操作效率。

比如 Gin 框架使用的開源組件 HttpRouter 就是采用這個方案。

go-zero 路由規則

在使用 go-zero 開發項目時,定義路由需要遵守如下規則:

  1. 路由必須以 / 開頭
  2. 路由節點必須以 / 分隔
  3. 路由節點中可以包含 :,但是 : 必須是路由節點的第一個字符,: 后面的節點值必須要在結請求體中有 path tag 聲明,用于接收路由參數
  4. 路由節點可以包含字母、數字、下劃線、中劃線

接下來就讓我們深入到源碼層面,相信看過源碼之后,你就會更懂這些規則的意義了。

go-zero 源碼實現

首先需要說明的是,底層數據結構使用的是二叉搜索樹,還不是很了解的同學可以看這篇文章:使用 Go 語言實現二叉搜索樹。

節點定義

先看一下節點定義:

// core/search/tree.go

const (
    colon = ':'
    slash = '/'
)

type (
    // 節點
    node struct {
        item     interface{}
        children [2]map[string]*node
    }

    // A Tree is a search tree.
    Tree struct {
        root *node
    }
)

重點說一下 children,它是一個包含兩個元素的數組,元素 0 存正常路由鍵,元素 1 存以 : 開頭的路由鍵,這些是 url 中的變量,到時候需要替換成實際值。

舉一個例子,有這樣一個路由 /api/:user,那么 api 會存在 children[0],user 會存在 children[1]。

具體可以看看這段代碼:

func (nd *node) getChildren(route string) map[string]*node {
    // 判斷路由是不是以 : 開頭
    if len(route) > 0 && route[0] == colon {
        return nd.children[1]
    }

    return nd.children[0]
}

路由添加

// Add adds item to associate with route.
func (t *Tree) Add(route string, item interface{}) error {
    // 需要路由以 / 開頭
    if len(route) == 0 || route[0] != slash {
        return errNotFromRoot
    }

    if item == nil {
        return errEmptyItem
    }

    // 把去掉 / 的路由作為參數傳入
    err := add(t.root, route[1:], item)
    switch err {
    case errDupItem:
        return duplicatedItem(route)
    case errDupSlash:
        return duplicatedSlash(route)
    default:
        return err
    }
}


func add(nd *node, route string, item interface{}) error {
    if len(route) == 0 {
        if nd.item != nil {
            return errDupItem
        }

        nd.item = item
        return nil
    }

    // 繼續判斷,看看是不是有多個 /
    if route[0] == slash {
        return errDupSlash
    }

    for i := range route {
        // 判斷是不是 /,目的就是去處兩個 / 之間的內容
        if route[i] != slash {
            continue
        }

        token := route[:i]
        
        // 看看有沒有子節點,如果有子節點,就在子節點下面繼續添加
        children := nd.getChildren(token)
        if child, ok := children[token]; ok {
            if child != nil {
                return add(child, route[i+1:], item)
            }

            return errInvalidState
        }

        // 沒有子節點,那么新建一個
        child := newNode(nil)
        children[token] = child
        return add(child, route[i+1:], item)
    }

    children := nd.getChildren(route)
    if child, ok := children[route]; ok {
        if child.item != nil {
            return errDupItem
        }

        child.item = item
    } else {
        children[route] = newNode(item)
    }

    return nil
}

主要部分代碼都已經加了注釋,其實這個過程就是樹的構建,如果讀過之前那篇文章,那這里還是比較好理解的。

路由查找

先來看一段 match 代碼:

func match(pat, token string) innerResult {
    if pat[0] == colon {
        return innerResult{
            key:   pat[1:],
            value: token,
            named: true,
            found: true,
        }
    }

    return innerResult{
        found: pat == token,
    }
}

這里有兩個參數:

  • pat:路由樹中存儲的路由。
  • token:實際請求的路由,可能包含參數值。

還是剛才的例子 /api/:user,如果是 api,沒有以 : 開頭,那就不會走 if 邏輯。

接下來匹配 :user 部分,如果實際請求的 url 是 /api/zhangsan,那么會將 user 作為 key,zhangsan 作為 value 保存到結果中。

下面是搜索查找代碼:

// Search searches item that associates with given route.
func (t *Tree) Search(route string) (Result, bool) {
    // 第一步先判斷是不是 / 開頭
    if len(route) == 0 || route[0] != slash {
        return NotFound, false
    }

    var result Result
    ok := t.next(t.root, route[1:], &result)
    return result, ok
}

func (t *Tree) next(n *node, route string, result *Result) bool {
    if len(route) == 0 && n.item != nil {
        result.Item = n.item
        return true
    }

    for i := range route {
        // 和 add 里同樣的提取邏輯
        if route[i] != slash {
            continue
        }

        token := route[:i]
        return n.forEach(func(k string, v *node) bool {
            r := match(k, token)
            if !r.found || !t.next(v, route[i+1:], result) {
                return false
            }
            // 如果 url 中有參數,會把鍵值對保存到結果中
            if r.named {
                addParam(result, r.key, r.value)
            }

            return true
        })
    }

    return n.forEach(func(k string, v *node) bool {
        if r := match(k, route); r.found && v.item != nil {
            result.Item = v.item
            if r.named {
                addParam(result, r.key, r.value)
            }

            return true
        }

        return false
    })
}

以上就是路由管理的大部分代碼,整個文件也就 200 多行,邏輯也并不復雜,通讀之后還是很有收獲的。

大家如果感興趣的話,可以找到項目更詳細地閱讀。也可以關注我,接下來還會分析其他模塊的源碼。

責任編輯:姜華 來源: AlwaysBeta
相關推薦

2023-08-10 08:00:42

令牌限流器計數器

2023-08-28 08:00:45

2025-05-26 04:00:00

2024-04-28 14:46:55

gozero微服務技巧

2012-03-12 16:42:54

測試

2024-04-22 08:26:37

協同編輯FigmaOT 算法

2024-01-15 07:42:37

Figma協同編輯算法

2011-08-01 09:08:49

程序員

2019-11-06 09:39:42

云成本企業云計算

2015-08-20 11:09:53

準入控制盈高

2021-05-13 08:00:00

軟件測試程序IT

2017-11-16 21:21:18

DevOps測試軟件開發

2022-12-07 11:21:30

Reactdiff

2021-07-06 10:03:05

軟件開發 技術

2017-11-23 19:14:00

CRM數字化軟件開發

2019-09-15 14:07:49

2015-07-30 11:21:16

代碼審查

2022-08-29 08:08:58

SQLOracleCPU

2022-08-03 09:11:31

React性能優化

2023-01-18 23:52:07

RTA用戶粒度運營
點贊
收藏

51CTO技術棧公眾號

国产精品欧美日韩一区| 波多野结衣精品| 久久 天天综合| 色中色综合影院手机版在线观看| a级片在线观看视频| 欧美日韩大片| 亚洲一级特黄| 亚洲成人免费网站| wwwwxxxx日韩| 精品精品导航| 欧美国产视频在线| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | 欧美色倩网站大全免费| 国产精品无码电影在线观看| 伦理片一区二区三区| 国产精品1区2区| 国产精品成人av性教育| 国产精品白浆一区二小说| 日韩大片在线观看| 亚洲精品电影久久久| 网站在线你懂的| 欧美日韩五码| 精品国产福利在线| 蜜臀av.com| freemovies性欧美| 91视频国产观看| 91亚色免费| 亚洲网站免费观看| 久热国产精品| 91成人精品网站| 精品小视频在线观看| 97偷自拍亚洲综合二区| 一区二区日韩精品| 玖玖爱在线观看| 精品自拍偷拍| 欧美r级电影在线观看| 亚洲美女性囗交| 日本不卡一二三| 精品久久久久久久久久久久久久| 国产 国语对白 露脸| 毛片在线播放a| 国产精品美女视频| 日韩激情久久| 国内在线精品| 久久先锋影音av鲁色资源网| 久久99导航| 天堂av在线免费| 成人网在线播放| 高清国产在线一区| 免费观看毛片网站| 成人av在线一区二区| 国产精品区一区| 黄色av一区二区三区| 成人丝袜高跟foot| 国产精品一区视频网站| 三级网站在线看| 99国产精品99久久久久久| 久久av一区二区三区漫画| 亚洲欧美日韩免费| 久久综合久久综合久久综合| 蜜桃视频在线观看成人| 国产在线一在线二| 中文字幕的久久| 一区二区视频在线播放| 超碰在线最新| 亚洲成人免费观看| 大陆极品少妇内射aaaaa| 日韩pacopacomama| 精品视频免费看| 中文字幕亚洲影院| 18国产精品| 精品视频在线播放| www.99热| 国模大胆一区二区三区| 午夜精品视频网站| 日韩三级一区二区| 久久国产福利国产秒拍| 99久久精品免费看国产一区二区三区| 黄色aaa大片| 国产欧美日韩在线| 潘金莲一级淫片aaaaa免费看| 欧美一卡二卡| 日韩欧美国产网站| 污污网站在线观看视频| 成人av婷婷| 国产香蕉一区二区三区在线视频 | 日韩精品毛片| 亚洲国产一区二区在线播放| 国产又黄又大又粗视频| 2020国产精品小视频| 亚洲а∨天堂久久精品9966| av女人的天堂| 欧美体内she精视频在线观看| 2019亚洲男人天堂| 一起草av在线| av电影天堂一区二区在线| 夜夜爽99久久国产综合精品女不卡| 亚洲精品天堂| 欧美综合色免费| 国产精品久久久久久亚洲av| 日本久久综合| 91精品国产高清久久久久久91| 中文字幕第31页| av午夜一区麻豆| 久久免费视频2| 涩涩涩视频在线观看| 3d动漫精品啪啪| 免费看污片网站| 欧美日韩a区| 国产精品视频久久久| 香蕉视频成人在线| 亚洲乱码国产乱码精品精可以看| 日本精品一区二区三区四区| 美国十次综合久久| 中文日韩在线视频| 特级西西444www大精品视频免费看| 国内久久婷婷综合| 先锋影音亚洲资源| 北岛玲heyzo一区二区| 亚洲精品在线三区| 久久国产精品国语对白| 日本不卡一区二区三区| 久久久综合香蕉尹人综合网| 色呦呦在线播放| 欧美久久久久中文字幕| 国产一区二区三区精品在线| 在线综合欧美| 国产精品一区二区三区在线| 性欧美猛交videos| 欧美日韩亚洲综合| 熟女俱乐部一区二区视频在线| 亚洲调教视频在线观看| 亚洲综合第一页| 日本欧美在线视频免费观看| 欧美中文字幕亚洲一区二区va在线| 丰满岳乱妇一区二区 | 亚洲图片欧美激情| 伊人国产在线视频| 三级电影一区| 国产精品入口福利| 福利视频在线看| 欧美优质美女网站| 日韩视频在线观看免费视频| 天堂成人国产精品一区| 免费在线成人av| 日本美女一区| 一区二区在线视频| 一区二区小视频| 国产精品国产自产拍在线| 在线观看国产一级片| 99精品在线观看| 欧美亚洲成人网| 每日更新在线观看av| 91福利国产精品| 四季av中文字幕| 久久电影国产免费久久电影| 亚洲欧美成人一区| 国产精品一区三区在线观看| 欧美成人免费观看| 噜噜噜久久,亚洲精品国产品| 图片区小说区国产精品视频| 成人精品在线观看视频| 日本网站在线观看一区二区三区 | 91久久免费视频| 麻豆视频观看网址久久| 老汉色影院首页| 成人av地址| 日本一欧美一欧美一亚洲视频| p色视频免费在线观看| 91麻豆精品91久久久久同性| 黄色一级视频免费| www久久精品| 性欧美1819| 国产精品v亚洲精品v日韩精品| 精品国产91亚洲一区二区三区www| 波多视频一区| 欧美成人高清视频| 日本人妖在线| 在线播放91灌醉迷j高跟美女| 国产网友自拍视频| 国产三级精品三级| 亚洲第一色av| 99国产成+人+综合+亚洲欧美| 午夜欧美性电影| 亚洲性视频在线| 日韩免费av一区二区| 黄色网址免费在线观看| 日韩成人激情视频| 中文字幕av片| 五月天欧美精品| 一级片黄色录像| 成人黄色大片在线观看 | 久久久97精品| 天堂а在线中文在线无限看推荐| 欧美日韩日日摸| 国产欧美日韩另类| 成人欧美一区二区三区小说| 人体私拍套图hdxxxx| 久久精品国产一区二区| 日本欧美黄色片| 在线看片不卡| 日韩三级电影| 日韩有码中文字幕在线| 91国产丝袜在线放| 国产极品一区| 日本人成精品视频在线| 美足av综合网| 久久精品亚洲精品| jizz日韩| 国产香蕉一区二区三区在线视频| 熟妇人妻中文av无码| 日韩一区国产二区欧美三区| 亚洲中文无码av在线| 五月天久久比比资源色| 免费一级肉体全黄毛片| 日韩毛片精品高清免费| 日本二区在线观看| 91亚洲精品乱码久久久久久蜜桃 | 一区二区视频免费| 欧美午夜精品伦理| 福利一区二区三区四区| 一区二区三区视频在线观看 | 亚洲国产精品视频| 九九精品视频免费| 国产欧美日韩不卡免费| www.免费av| jlzzjlzz国产精品久久| 亚洲成人福利视频| 国产精品一区二区视频| www.色欧美| 久久99精品视频| 成人3d动漫一区二区三区| 亚洲一区国产| 成人一对一视频| 最新成人av网站| 岛国大片在线播放| 亚洲电影成人| 搞av.com| 国产日韩一区| 波多野结衣家庭教师在线| 国产精品毛片| 国产又黄又大又粗视频| 天堂在线一区二区| 国产97色在线 | 日韩| 日本伊人精品一区二区三区观看方式| 久久精品网站视频| 丝袜亚洲另类丝袜在线| 午夜免费精品视频| 免费在线观看视频一区| 欧美大尺度做爰床戏| 麻豆国产精品视频| 亚洲欧美日韩三级| 国产精品中文字幕一区二区三区| 999在线精品视频| 国产精一品亚洲二区在线视频| 三级网站免费看| 国产·精品毛片| 老司机午夜免费福利| 2023国产精品视频| 熟女少妇内射日韩亚洲| 国产精品久久看| 久久精品视频免费在线观看| 亚洲a一区二区| 中文字幕一区在线播放| 欧美三级电影一区| 国产黄频在线观看| 亚洲级视频在线观看免费1级| 青草久久伊人| xxxxx91麻豆| 国产丝袜在线播放| 国产成人涩涩涩视频在线观看 | 日本sm残虐另类| 免费av不卡在线| 成人精品国产免费网站| 国产特黄级aaaaa片免| 国产精品私人影院| 在线免费观看亚洲视频| 香蕉久久一区二区不卡无毒影院| 91在线视频免费播放| 7777精品伊人久久久大香线蕉的| 国产高清在线免费| 亚洲天天在线日亚洲洲精| 国产在线一区二区视频| 91精品国产91久久久久| 麻豆久久久久| 久久av免费观看| 91精品啪在线观看国产18| 亚洲熟妇av日韩熟妇在线| 免费视频最近日韩| 精品人妻伦一二三区久| 亚洲国产精品黑人久久久| 亚洲精选中文字幕| 69av视频在线观看| 日韩精品一区二区三区视频| 欧美中文在线| 九九九热精品免费视频观看网站| 成人爽a毛片免费啪啪| 亚洲在线免费看| 精品成人影院| 日本在线xxx| 国产精品小仙女| 中文字幕免费在线看线人动作大片| 一区二区免费视频| 中文字幕免费在线看| 日韩电影免费在线观看中文字幕| 久热国产在线| 国产精品欧美激情| 林ゆな中文字幕一区二区| 桥本有菜av在线| 日本在线观看不卡视频| 国产 中文 字幕 日韩 在线| 亚洲色欲色欲www| 亚洲av无码精品一区二区| 亚洲国产成人精品一区二区| 黄色网页在线播放| 国产精品久久久久久久电影| 精品网站aaa| 欧美亚洲色图视频| 韩国欧美国产1区| 国产探花视频在线播放| 欧美日韩亚洲一区二区| 亚洲精品97久久中文字幕无码| 日韩视频亚洲视频| 国产精成人品2018| 日本高清不卡三区| 久久九九99| 国产熟妇久久777777| 日韩欧美成人网| 五月激情丁香婷婷| 韩国精品久久久999| ady日本映画久久精品一区二区| 中文视频一区视频二区视频三区| 日韩av中文字幕一区二区| 偷拍夫妻性生活| 日本乱人伦aⅴ精品| 欧美日本网站| 奇门遁甲1982国语版免费观看高清 | 久久精品影视| 97人人爽人人| 亚洲欧洲国产日韩| 国产日本精品视频| 另类图片亚洲另类| 亚洲一二三区视频| 国产精品久久久久9999爆乳| 成人丝袜视频网| 亚洲男人第一av| 日韩精品有码在线观看| 美女网站在线看| 欧美lavv| 免费观看成人av| 午夜爽爽爽男女免费观看| 欧美一二三区在线观看| 久久不射影院| 久久久人人爽| 免费观看成人鲁鲁鲁鲁鲁视频| 老司机深夜福利网站| 91精品国产91综合久久蜜臀| 欧美人体视频xxxxx| 国产视频不卡| 天堂久久久久va久久久久| 国产精品久久久视频| 欧美卡1卡2卡| 好吊日av在线| 欧美中日韩免费视频| 久久成人久久鬼色| 69av.com| 亚洲美女视频网| 欧美爱爱视频| 人妻激情另类乱人伦人妻| 99久久综合国产精品| 色老头一区二区| 俺去啦;欧美日韩| 亚洲日本va| 欧美精品第三页| 亚洲精品你懂的| 六月丁香色婷婷| 国产精品视频1区| 欧美视频久久| 97在线观看免费视频| 日韩一区二区视频| sese综合| 日韩精品免费一区| 久久综合久久综合九色| 97精品人妻一区二区三区在线| 欧美黑人极品猛少妇色xxxxx | 午夜久久久久久久久久久| 成人99免费视频| 97久久人国产精品婷婷| 91高潮精品免费porn| 婷婷综合网站| 国产中文字幕一区二区| 欧美福利视频一区| 亚洲欧美小说色综合小说一区| 丰满女人性猛交| 久久久噜噜噜久久中文字幕色伊伊| 97人妻精品一区二区三区软件| 91精品国产高清久久久久久| 一区二区日韩欧美| av网站免费在线看| 亚洲国产精品免费|