Spring Cloud Gateway

zuul终究还是被时代淘汰了,spring基本上也逐渐放弃了Netflix平台,自己搞起了gateway。这不得不聊起一个人 Spencer Gibb,他是zuul的核心开发,带领一群有志青年,放弃zuul,转战spring cloud gateway。

应用搭建

其maven依赖如下:

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

之后,只需要写个简单的spring boot程序就可以了,与zuul不同的是,gateway没有@Enable开头的开关:

java 复制代码
@SpringBootApplication
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

这就是gateway与zuul设计哲学的不同。

网关配置

光完成上述代码肯定不够,因为没有配置转发。以下是配置文件的一个例子:

yml 复制代码
server:
  port: 80 # 网关端口

spring:
  cloud:
    gateway:
      routes:
        - id: user_route
          # 直接写死目标服务的 IP 和端口
          uri: http://127.0.0.1:8001
          predicates:
            - Path=/user/**

之后就可以正常转发了。

谓词配置

配置中的predicates是gateway的谓词,这部分可谓非常复杂了。上述例子里用的是路径谓词。此外我还整理了其他比较好用的谓词.

谓词名称 用途 典型场景
Path 匹配请求路径 /api/ 转发给某个服务
Query 匹配请求参数 根据 URL 中的参数(如版本号)分流
Header 匹配请求头 根据 User-Agent 或自定义 Header 鉴权
Method 匹配请求方法 只允许 GET 或 POST 请求通过
Cookie 匹配 Cookie 针对特定用户群体的灰度发布
Host 匹配域名 基于域名的路由(如 *.abc.com
RemoteAddr 匹配客户端 IP 黑白名单、IP 限流
After/Before 匹配时间 活动期间开启特定页面,或维护窗口

过滤器

除了谓词以外,gateway还提供了过滤器配置,以达到更精致的网关控制。以下是常见的过滤器:

分类 过滤器名称 (Filter Name) 核心作用
请求处理 AddRequestHeader 给请求头添加自定义信息
AddRequestParameter 给请求添加参数
RewritePath 重写请求路径(最常用)
StripPrefix 截断请求路径前缀
RequestRateLimiter 请求限流(令牌桶算法)
响应处理 AddResponseHeader 给响应头添加信息
DedupeResponseHeader 去除响应头中重复的值
SetStatus 修改返回的状态码
路由增强 Hystrix 熔断保护(旧版)
RequestSize 限制请求包大小
Retry 失败自动重试

转发实现

gateway是怎么转发的?gateway是基于WebFlux技术的。gateway写了一个RoutePredicateHandlerMapping,该类实现了HandlerMapping接口,所以充当了传统servlet里控制器的角色。核心方法在lookupRoute里。在追踪gateway源码时我们可以记录一下堆栈的变化。

  1. 线程Thread[reactor-http-nio-2,5,main]

at org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping.lookupRoute(RoutePredicateHandlerMapping.java:128)

at org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping.getHandlerInternal(RoutePredicateHandlerMapping.java:87)

at org.springframework.web.reactive.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:181)

  1. 线程Thread[reactor-http-nio-2,5,main]

at org.springframework.cloud.gateway.handler.FilteringWebHandler.handle(FilteringWebHandler.java:77)

at org.springframework.web.reactive.result.SimpleHandlerAdapter.handle(SimpleHandlerAdapter.java:45)

at org.springframework.web.reactive.DispatcherHandler.invokeHandler(DispatcherHandler.java:161)

  1. 线程Thread[reactor-http-nio-2,5,main]

at org.springframework.cloud.gateway.filter.NettyRoutingFilter.filter(NettyRoutingFilter.java:104)

at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:138)

at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44)

NettyRoutingFilter这个类里终于找到了转发的代码了,我只贴一行代码,不过这行代码可够长的了:

java 复制代码
Flux<HttpClientResponse> responseFlux = this.httpClient.headers(headers -> {
			headers.add(httpHeaders);
			if (preserveHost) {
				String host = request.getHeaders().getFirst(HttpHeaders.HOST);
				headers.add(HttpHeaders.HOST, host);
			}
			else {
				// let Netty set it based on hostname
				headers.remove(HttpHeaders.HOST);
			}
		}).request(method).uri(url).send((req, nettyOutbound) -> {
			if (log.isTraceEnabled()) {
				nettyOutbound.withConnection(connection -> log.trace(
						"outbound route: " + connection.channel().id().asShortText()
								+ ", inbound: " + exchange.getLogPrefix()));
			}
			return nettyOutbound.send(request.getBody()
					.map(dataBuffer -> ((NettyDataBuffer) dataBuffer).getNativeBuffer()));
		}).responseConnection((res, connection) -> {

			// 省略很多很多代码。。。。。。。

			return Mono.just(res);
		});
相关推荐
Moe4883 分钟前
Spring AI Advisors:从链式增强到递归顾问
java·后端
敖正炀8 分钟前
ReentrantReadWriteLock、ReentrantLock、synchronized 对比
java
cike_y18 分钟前
Java反序列化漏洞-Shiro721流程分析
java·反序列化·shiro框架
极创信息40 分钟前
信创系统认证服务怎么做?从适配到验收全流程指南
java·大数据·运维·tomcat·健康医疗
格鸰爱童话1 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
白宇横流学长1 小时前
停车场管理系统的设计与实现
java
Flittly1 小时前
【SpringAIAlibaba新手村系列】(18)Agent 智能体与今日菜单应用
java·spring boot·agent
木井巳1 小时前
【递归算法】目标和
java·算法·leetcode·决策树·深度优先
亦暖筑序1 小时前
手写 Spring AI Agent:让大模型自主规划任务,ReAct 模式全流程拆解
java·人工智能·spring
敖正炀1 小时前
ReentrantLock 与 synchronized对比
java