spring cloud 网关性能瓶颈分析及优化
背景
在公司的开放平台中需要对外保留接口,此时需要一个公共层来处理公共逻辑,限流,验证权限,所以需要一个网关
技术选型
此处从网上贴图
网关整体设计 及架构
优化背景
在上线之后,对接服务商增多,挂载接口增多的情况下,需要测试性能瓶颈。此时发现和官方给出的数据差别较大
直接压测
去掉日志之后
性能有提升,但是还是不符合预期,此时观察到jvm的情况,YGC次数太多
修改jvm参数
此时性能提升,但是还不满意,继续探索
怀疑是路由数量导致的问题,进行验证
验证之后,确实是路由数量会导致吞吐量的下降,进行代码分析
性能瓶颈代码分析
DispatcherHandler :接收到请求,匹配 HandlerMapping ,此处会匹配到
RoutePredicateHandlerMapping 。
RoutePredicateHandlerMapping :接收到请求,匹配 Route 。
读RoutePredicateHandlerMapping 源码发现:获取具体的路由会:
调用 RouteLocator#getRoutes() 方法,获得全部 Route ,
并调用 Predicate#test(ServerWebExchange) 方法,顺序匹配一个 Route。
此时会遍历缓存中的路由列表,然后获取每一个路由的断言器
,将请求信息传入断言器工厂,去判断是否和当前的路由匹配,
如果情况最糟糕时候,最终匹配到的路由排在
最后一个,此处就会出现性能问题
改造方式1
从官网看到一个修改的思路,结合我们SCG对Api的设计,因为路由和Api是一一对应的,知道Api其实已经可以知道路由信息了,不用走gateway自己那套功能强大但性能有损耗的路由规则解析,我们何不在构建路由信息的时候同时增加一个缓存Map,key为路由ID,这个ID是可以自定义的,我们可以让Api的唯一标识作为路由的ID,Map的value就是路由的信息,这样当请求过来,根据我们的协议规则可以解析出Api,有了Api就可以通过这个Map拿到对应的路由对象了,可以绕过RoutePredicateHandlerMapping#lookupRoute的原有逻辑。
将原有的挨个匹配改为key-value的精准匹配,所以需要修改一下源代码,官方已经给出了修改方法,结合我们的情况,觉得重写一下底层的RoutePredicateHandlerMapping和CachingRouteLocator
修改CachingRouteLocator代码如下:
RoutePredicateHandlerMapping代码修改
增加以下代码
修改完成之后,逻辑就是在原有的路由保存代码中,增加一个新的map缓存,key为路由ID,在匹配代码前从请求中获取路由的唯一标识,路由ID,然后精准匹配,匹配不到走原有逻辑
改造方式2
这部分代码不展示了,只说实现的逻辑,改造完成之后的结果
整个优化过程结果展示
改造思路3
这个只是一个方向,本人尚未实现