Skip to content

动态路由的原理

1107字约4分钟

2024-10-11

web框架选择

Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 httprouter,速度提高了 40 倍。同时GIN框架本身具有丰富的特性

问题分析

gin框架支持在服务启动时注册路由,但是路由 不支持动态注册或者动态下线 ,路由一旦注册,除非服务重启,否则无法变更注册的路由。此处面临两个问题:

  • 注册 了一个网关接口之后,如何在不重启服务的情况下动态 上线 接口?
  • 移除 了一个网关接口之后,如何在不重启服务的情况下动态 下线 接口?

如何解决上述两个问题即为实现动态路由的关键。

首先,我们简要分析一下请求到了我们的服务之后,是如何执行的

如果想实现 动态路由 ,路由必然不可能是直接注册到路由树上的,从上面简易的流程图可以看出,在路由未注册的情况下,我们会走到 路由未注册 逻辑 而路由未注册,GIN会返回 404 Not Found , 这与我们预期不符,我们期望的是如下流程:

问题解决

两组处理流程对比之下, 核心区别在于 如何处理未注册的路由请求 , 这样, 我们期望的 动态路由 问题即简化成了 如何修改GIN未注册路由请求处理的默认行为

问题到此处,就变得简单且具体了,GIN本身即提供了 修改默认行为 的方式:

route := gin.Default()
router.NoRoute(func(ctx *gin.context) {
    // 这里放置拦截到未注册路由的处理逻辑
    // 具体如何实现,基于业务诉求自由实现
    // 在网关动态路由场景下,后续会具体解释如何实现动态路由
})

和注册普通路由一样, NoRoute 是一种特殊的路由,当访问的路由未注册时,对应的请求会转发到 NoRoute 中所注册的 Handler 进行处理。 事实上,不通过NoRoute,通过 自定义全局中间件 也可实现对应诉求,但是既然 GIN 暴露了 NoRoute 的能力,建议使用此能力。

总结

动态路由 听起来挺唬人,好像是一种十分高大上的技术,十分高深,实则不然。 动态路由本质上就是重写默认的404行为 。 抽丝剥茧之下,会发现其实原理很简单,并不复杂。当然, 原理简单并不等于就能做好 ,摸清原理,后续实现依旧是对能力的一个考验。