当前位置: 首页 > news >正文

企业网站建立庆云县有几家苏州知名网站建设设计公司

企业网站建立庆云县有几家,苏州知名网站建设设计公司,app和网站开发的成本,有创意的婚纱网站模板下载原文链接#xff1a; go-zero 是如何做路由管理的#xff1f; go-zero 是一个微服务框架#xff0c;包含了 web 和 rpc 两大部分。 而对于 web 框架来说#xff0c;路由管理是必不可少的一部分#xff0c;那么本文就来探讨一下 go-zero 的路由管理是怎么做的#xff0c…原文链接 go-zero 是如何做路由管理的 go-zero 是一个微服务框架包含了 web 和 rpc 两大部分。 而对于 web 框架来说路由管理是必不可少的一部分那么本文就来探讨一下 go-zero 的路由管理是怎么做的具体采用了哪种技术方案。 路由管理方案 路由管理方案有很多种具体应该如何选择应该根据使用场景以及实现的难易程度做综合分析下面介绍常见的三种方案。 注意这里只是做一个简单的概括性对比更加详细的内容可以看这篇文章HTTP Router 算法演进。 标准库方案 最简单的方案就是直接使用 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 开发项目时定义路由需要遵守如下规则 路由必须以 / 开头路由节点必须以 / 分隔路由节点中可以包含 :但是 : 必须是路由节点的第一个字符: 后面的节点值必须要在结请求体中有 path tag 声明用于接收路由参数路由节点可以包含字母、数字、下划线、中划线 接下来就让我们深入到源码层面相信看过源码之后你就会更懂这些规则的意义了。 go-zero 源码实现 首先需要说明的是底层数据结构使用的是二叉搜索树还不是很了解的同学可以看这篇文章使用 Go 语言实现二叉搜索树 节点定义 先看一下节点定义 // core/search/tree.goconst (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 itemreturn 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[i1:], item)}return errInvalidState}// 没有子节点那么新建一个child : newNode(nil)children[token] childreturn add(child, route[i1:], 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 作为 keyzhangsan 作为 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 Resultok : 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.itemreturn 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[i1:], 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.itemif r.named {addParam(result, r.key, r.value)}return true}return false}) }以上就是路由管理的大部分代码整个文件也就 200 多行逻辑也并不复杂通读之后还是很有收获的。 大家如果感兴趣的话可以找到项目更详细地阅读。也可以关注我接下来还会分析其他模块的源码。 以上就是本文的全部内容如果觉得还不错的话欢迎点赞转发和关注感谢支持。 推荐阅读 使用 Go 语言实现二叉搜索树HTTP Router 算法演进
http://www.tj-hxxt.cn/news/216643.html

相关文章:

  • 图标的网站网站优化哪里可以做
  • 饰品网站建设规划书一个域名多个网站
  • 网站备案时间湛江人怎么样
  • c2c网站 多钱怎么改网站标题
  • 2010网站建设管理国际最新军事新闻
  • 新野微网站建设上海出大事啦
  • 网站年报公示怎么做邵阳 网站开发 招聘
  • 未来的门户网站开发公司组织架构图模板
  • 网站建设关键词排名优化上海人才网站官网入口
  • 工装设计效果图网站创意网红墙图片
  • 高端网站建设的要求江苏seo排名
  • 专做动漫的网站家庭装修设计软件哪个好用
  • 营销型企业网站策划方案互联网广告销售好做吗
  • 快速优化网站建设自己做的网站如何在百度被搜索到
  • 网站建设上市公司宁波住房和城乡建设官网
  • 广州网站设计易企建站怎样申请免费网站域名
  • 阿里云备案 网站备案域名做设计去哪个网站找素材
  • wordpress网站主机名wordpress 自定义页眉
  • 平台网站开发风险找哪些公司做网站
  • 深圳品牌网站制作报价网站响应方案
  • 邯郸哪里有做网站的李网页设计师相关职业前景
  • 安全联盟可信网站认证做网站服务器配置应该怎么选
  • 网站公司建设个服务号多少钱北京蓝杉网站建设公司
  • 高端大气企业网站模板建设宁夏分行互联网站
  • 中山技术支持中山网站建设技术培训ui设计
  • 河源北京网站建设wordpress推送到百度
  • 丹阳网站建设公司毕业生就业推荐表模板网站开发
  • 下花园区住房和城乡建设局网站电子商务网站建设一体化教案
  • 网站开发过时了做一个商城网站多少钱
  • 河北网站建设与推广wordpress评论导出