动态路由的原理
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行为
。 抽丝剥茧之下,会发现其实原理很简单,并不复杂。当然, 原理简单并不等于就能做好
,摸清原理,后续实现依旧是对能力的一个考验。