spring|Spring Cloud Gateway一次请求调用源码解析

文章图片
文章图片
文章图片
文章图片
一 前言 最近通过深入学习Spring Cloud Gateway发现这个框架的架构设计非常简单、有效 , 很多组件的设计都非常值得学习 , 本文就Spring Cloud Gateway做一个简单的介绍 , 以及针对一次请求Spring Cloud Gateway的处理流程做一个较为详细的分析 。
二 简介 Spring Cloud Gateway 即Spring官方推出的一款API网关 , 该框架包含了Spring5、SpringBoot2、Project Reactor , 其中底层通信框架用的netty 。 Spring Cloud Gateway在推出之初的时候 , Netflix公司已经推出了类似功能的API网关框架ZUUL , 但ZUUL有一个缺点是通信方式是阻塞的 , 虽然后来升级到了非阻塞式的ZUUL2 , 但是由于Spring Cloud Gateway已经推出一段时间 , 同时自身也面临资料少、维护性较差的因素没有被广泛应用 。
1 关键术语
在使用Spring Cloud Gateway的时候需要理解三个模块 , 即
Route:
即一套路由规则 , 是集URI、predicate、filter等属性的一个元数据类 。
Predicate:
这是Java8函数式编程的一个方法 , 这里可以看做是满足什么条件的时候 , route规则进行生效 。
Filter:
filter可以认为是Spring Cloud Gateway最核心的模块 , 熔断、安全、逻辑执行、网络调用都是filter来完成的 , 其中又细分为gateway filter和global filter , 区别在于是具体一个route规则生效还是所有route规则都生效 。
可以先上一段代码来看看:
@RequestMapping(\"/paramTest\") public Object paramTest(@RequestParam MapStringObjectparam) { return param.get(\"name\");@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes() .route(\"path_route\" r -r.path(\"/get\") .filters(f -f.addRequestParameter(\"name\" \"value\")) .uri(\"forward:///paramTest\")) .build();route方法代表的就是一个路由规则; path方法代表的就是一个predicate , 背后的现实是PathRoutePredicateFactory , 在这段代码的含义即当路径包含/get的时候 , 当前规则生效 。filters方法的意思即给当前路由规则添加一个增加请求参数的filter , 每次请求都对参数里添加 name:value 的键值对; uri 方法的含义即最终路由到哪里去 , 这里的forward前缀会将请求交给spring mvc的DispatcherHandler进行路由 , 进行本机的逻辑调用 , 除了forward以外还可以使用http、https前缀进行http调用 , lb前缀可以在配置注册中心后进行rpc调用 。
上图是Spring Cloud Gateway官方文档给出的一个工作原理图 , Spring Cloud Gateway 接收到请求后进行路由规则的匹配 , 然后交给web handler 进行处理 , web handler 会执行一系列的filter逻辑 。
三 流程分析 1 接受请求
Spring Cloud Gateway的底层框架是netty , 接受请求的关键类是ReactorHttpHandlerAdapter , 做的事情很简单 , 就是将netty的请求、响应转为http的请求、响应并交给一个http handler执行后面的逻辑 , 下图为该类的源码仅保留核心逻辑 。
@Override public MonoVoidapply(HttpServerRequest request HttpServerResponse response) { NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.alloc()); ServerHttpRequest adaptedRequest; ServerHttpResponse adaptedResponse; //转换请求 try { adaptedRequest = new ReactorServerHttpRequest(request bufferFactory); adaptedResponse = new ReactorServerHttpResponse(response bufferFactory);catch (URISyntaxException ex) { if (logger.isWarnEnabled()) { ...... return this.httpHandler.handle(adaptedRequest adaptedResponse) .doOnError(ex -logger.warn(\"Handling completed with error: \" + ex.getMessage())) .doOnSuccess(aVoid -logger.debug(\"Handling completed with success\"));2 WEB过滤器链
- 6月23日消息|全面自主可控!首个全链路国产操作系统OpenCloudOS
- spring|纯白ITX来了,还支持GEAR 1高频内存!新款七彩虹B660迷你主板测试
- spring|iPhone14系列再次被确认:配色、屏幕、电池容量、价格基本清晰了
- iOS 16 Beta 2新增流量备份iCloud 网友吐槽
- 苹果|iOS 16 Beta 2新增流量备份iCloud 网友吐槽:备份完一套房子没了
- 全面自主可控!首个全链路国产化操作系统OpenCloudOS发布源社区项目
- 百度|IDC报告:百度智能云AI Cloud市场份额连续六次第一
- 用友U9 cloud新征程 从普惠制造到高效增长的数智力量
- spring|安全管理框架,用Shiro还是用Spring Security?
- spring|这价格值得抢!锐龙7-6800H游戏本,配满血RTX3060高分屏6999元
