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

在这里插入图片描述

这个只是一个方向,本人尚未实现

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐