Spring?Cloud?Gateway?WebFlux?模式架構(gòu)場景分析
1. 入口類及關(guān)鍵類關(guān)系
1.1 入口類
Spring Cloud Gateway WebFlux 模式的入口類是 GatewayAutoConfiguration,這是整個 WebFlux 模式的"總指揮"。它負(fù)責(zé)配置所有 Gateway 需要的組件。
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.server.webflux.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,
GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
// 核心 Bean 定義
}關(guān)鍵特性說明:
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })- 這個很關(guān)鍵!Gateway 必須在 WebFlux 的默認(rèn)配置之前加載
- 為什么?因?yàn)?Gateway 需要注冊自己的
HandlerMapping(RoutePredicateHandlerMapping) - 如果 WebFlux 的默認(rèn)配置先加載,可能會注冊其他的 HandlerMapping,導(dǎo)致路由沖突
- Gateway 的 HandlerMapping 優(yōu)先級更高,會優(yōu)先處理請求
@ConditionalOnClass(DispatcherHandler.class)- 這個注解確保只有在 WebFlux 存在時才加載 Gateway
DispatcherHandler是 WebFlux 的核心組件,類似于 WebMVC 的DispatcherServlet- 如果沒有 WebFlux,Gateway WebFlux 模式就無法工作
@ConditionalOnProperty
# 可以通過配置控制是否啟用
spring:
cloud:
gateway:
server:
webflux:
enabled: true # 默認(rèn)啟用,可以設(shè)置為 false 禁用配置的核心組件:
RouteLocator:路由定位器,負(fù)責(zé)提供路由列表FilteringWebHandler:過濾器處理器,負(fù)責(zé)執(zhí)行過濾器鏈RoutePredicateHandlerMapping:路由匹配器,負(fù)責(zé)匹配請求到路由GatewayProperties:Gateway 配置屬性
1.2 關(guān)鍵類關(guān)系圖

1.3 核心組件說明
RoutePredicateHandlerMapping
這是 Gateway 的路由匹配器,負(fù)責(zé)找到匹配的路由。它繼承自 Spring WebFlux 的 AbstractHandlerMapping。
工作原理:
@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
// 1. 查找匹配的路由(異步操作)
return lookupRoute(exchange)
.map(route -> {
// 2. 把路由信息存儲到 Exchange 的屬性中
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, route);
// 3. 返回 FilteringWebHandler 作為處理器
return webHandler;
});
}實(shí)際例子:
// 假設(shè)有這些路由配置
routes = [
{ id: "user-service", path: "/api/users/**", uri: "http://user-service" },
{ id: "order-service", path: "/api/orders/**", uri: "http://order-service" }
]
// 請求:GET /api/users/123
// lookupRoute() 會:
// 1. 遍歷所有路由
// 2. 使用 AsyncPredicate 異步匹配
// 3. 找到匹配的路由:user-service
// 4. 返回 FilteringWebHandler關(guān)鍵點(diǎn):
lookupRoute()返回Mono<Route>,是異步的- 路由匹配使用
AsyncPredicate,支持異步條件判斷 - 匹配成功后,路由信息存儲在
ServerWebExchange的屬性中
FilteringWebHandler
這是 Gateway 的核心請求處理器,負(fù)責(zé)執(zhí)行過濾器鏈。它實(shí)現(xiàn)了 Spring WebFlux 的 WebHandler 接口。
工作原理:
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
// 1. 從 Exchange 中獲取路由信息(路由匹配時設(shè)置的)
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
// 2. 獲取合并后的過濾器列表(全局過濾器 + 路由過濾器)
List<GatewayFilter> combined = getCombinedFilters(route);
// 3. 創(chuàng)建過濾器鏈并執(zhí)行
return new DefaultGatewayFilterChain(combined).filter(exchange);
}實(shí)際例子:
// 假設(shè)路由配置了這些過濾器
route.filters = [
AddRequestHeaderFilter,
RateLimitFilter,
NettyRoutingFilter // 最后一個,負(fù)責(zé)實(shí)際轉(zhuǎn)發(fā)請求
]
// FilteringWebHandler 會:
// 1. 合并全局過濾器和路由過濾器
// 2. 按 Order 排序
// 3. 創(chuàng)建過濾器鏈
// 4. 依次執(zhí)行過濾器過濾器鏈執(zhí)行:
// 過濾器鏈的實(shí)現(xiàn)(責(zé)任鏈模式)
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
// 創(chuàng)建下一個鏈節(jié)點(diǎn)
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
// 執(zhí)行當(dāng)前過濾器,傳入下一個鏈節(jié)點(diǎn)
return filter.filter(exchange, chain);
}
return Mono.empty(); // 所有過濾器執(zhí)行完畢
});
}
}RouteLocator
路由定位器,負(fù)責(zé)提供路由列表。Gateway 支持多個 RouteLocator,可以組合使用。
工作原理:
@Bean
@Primary
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
// 1. 組合多個 RouteLocator
CompositeRouteLocator composite = new CompositeRouteLocator(
Flux.fromIterable(routeLocators)
);
// 2. 添加緩存(提高性能)
return new CachingRouteLocator(composite);
}實(shí)際例子:
// 可以有多個 RouteLocator
RouteLocator[] locators = [
PropertiesRouteDefinitionLocator, // 從配置文件讀取路由
DiscoveryClientRouteDefinitionLocator, // 從服務(wù)發(fā)現(xiàn)讀取路由
InMemoryRouteDefinitionRepository // 從內(nèi)存(API)讀取路由
]
// CompositeRouteLocator 會合并所有路由
// 返回 Flux<Route>,包含所有路由路由來源:
配置文件:PropertiesRouteDefinitionLocator
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081服務(wù)發(fā)現(xiàn):DiscoveryClientRouteDefinitionLocator
// 自動從 Eureka/Consul 等服務(wù)注冊中心發(fā)現(xiàn)服務(wù) // 為每個服務(wù)自動創(chuàng)建路由
API 動態(tài)配置:InMemoryRouteDefinitionRepository
// 通過 API 動態(tài)添加/刪除路由 routeDefinitionRepository.save(routeDefinition);
2. 關(guān)鍵流程描述
2.1 請求處理流程時序圖

2.2 路由匹配流程
路由匹配是 Gateway 的核心功能。讓我們用一個實(shí)際例子來說明整個流程:
場景:客戶端請求 GET /api/users/123
詳細(xì)流程:
DispatcherHandler 接收 HTTP 請求
客戶端 → DispatcherHandler → Gateway
DispatcherHandler 是 WebFlux 的請求分發(fā)器,類似于 WebMVC 的 DispatcherServlet
它會把請求交給合適的 HandlerMapping 處理
Gateway 的 RoutePredicateHandlerMapping 優(yōu)先級很高,會優(yōu)先處理
RoutePredicateHandlerMapping 從 RouteLocator 獲取所有路由
// 獲取所有路由(返回 Flux<Route>,是響應(yīng)式的)
Flux<Route> routes = routeLocator.getRoutes();
// 實(shí)際的路由列表可能是:
// [
// { id: "user-service", path: "/api/users/**", uri: "http://user-service" },
// { id: "order-service", path: "/api/orders/**", uri: "http://order-service" }
// ]RouteLocator 可能從多個來源獲取路由(配置文件、服務(wù)發(fā)現(xiàn)、API)
返回的是 Flux<Route>,是響應(yīng)式的流
使用 AsyncPredicate 異步匹配路由
// 異步匹配路由
return routes
.filterWhen(route -> {
// 使用 AsyncPredicate 異步匹配
return route.getPredicate().test(exchange);
})
.next(); // 返回第一個匹配的路由匹配過程:
// 路由1:user-service
AsyncPredicate predicate1 = exchange -> {
String path = exchange.getRequest().getPath().value();
return Mono.just(path.startsWith("/api/users/")); // 異步返回 true/false
};
// 路徑 "/api/users/123" 匹配 "/api/users/**" ?
// 路由2:order-service
AsyncPredicate predicate2 = exchange -> {
String path = exchange.getRequest().getPath().value();
return Mono.just(path.startsWith("/api/orders/")); // 異步返回 false
};
// 路徑 "/api/users/123" 不匹配 "/api/orders/**" ?- 使用
AsyncPredicate異步匹配,支持異步條件判斷 - 可以在這里做異步操作(比如查詢 Redis、數(shù)據(jù)庫等)
- 返回
Mono<Boolean>,不會阻塞線程
找到匹配的路由后,將路由信息存儲到 ServerWebExchange 的屬性中
// 匹配成功后 Route matchedRoute = ...; // user-service 路由 // 存儲路由信息到 Exchange 的屬性中 exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, matchedRoute); exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, matchedRoute.getUri());
- 路由信息存儲在
ServerWebExchange的屬性中 - 后續(xù)的過濾器可以從這里獲取路由信息
- 比如
NettyRoutingFilter會從這里獲取目標(biāo) URI
返回 FilteringWebHandler 作為處理器
// 返回 FilteringWebHandler return Mono.just(webHandler);
FilteringWebHandler會負(fù)責(zé)執(zhí)行過濾器鏈- 最終會調(diào)用
NettyRoutingFilter轉(zhuǎn)發(fā)請求到下游服務(wù)
完整示例:
# 配置文件
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://user-service:8081
predicates:
- Path=/api/users/**
- Method=GET匹配過程:
- 請求
GET /api/users/123到達(dá) - 路徑
/api/users/123匹配/api/users/**? - 方法
GET匹配GET? - 找到匹配的路由
user-service - 返回
FilteringWebHandler,目標(biāo) URI 是http://user-service:8081
2.3 過濾器鏈執(zhí)行流程
過濾器鏈?zhǔn)?Gateway 的核心機(jī)制。讓我們用一個實(shí)際例子來說明:
場景:請求已經(jīng)匹配到路由,現(xiàn)在需要執(zhí)行過濾器鏈
詳細(xì)流程:
FilteringWebHandler 從路由中獲取過濾器列表
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR); List<GatewayFilter> routeFilters = route.getFilters(); // 假設(shè)路由配置了這些過濾器: // [AddRequestHeaderFilter, RateLimitFilter]
- 從路由中獲取路由級別的過濾器
- 這些過濾器只應(yīng)用于當(dāng)前路由
合并全局過濾器和路由過濾器,按 Order 排序
// 全局過濾器(應(yīng)用于所有路由)
List<GlobalFilter> globalFilters = [
LoadBalancerClientFilter, // Order: 10100
NettyRoutingFilter, // Order: Ordered.LOWEST_PRECEDENCE
NettyWriteResponseFilter // Order: Ordered.LOWEST_PRECEDENCE - 1
];
// 路由過濾器
List<GatewayFilter> routeFilters = [
AddRequestHeaderFilter, // Order: 1000
RateLimitFilter // Order: -100
];
// 合并并排序
List<GatewayFilter> combined = [
RateLimitFilter, // -100 (最高優(yōu)先級)
AddRequestHeaderFilter, // 1000
LoadBalancerClientFilter, // 10100
NettyRoutingFilter, // LOWEST_PRECEDENCE
NettyWriteResponseFilter // LOWEST_PRECEDENCE - 1
];- 全局過濾器 + 路由過濾器 = 合并后的過濾器列表
- 按
Order排序,數(shù)字越小優(yōu)先級越高 Ordered.LOWEST_PRECEDENCE是最大整數(shù),優(yōu)先級最低
創(chuàng)建 DefaultGatewayFilterChain,實(shí)現(xiàn)責(zé)任鏈模式
// 創(chuàng)建過濾器鏈
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(combined);
// 過濾器鏈的內(nèi)部實(shí)現(xiàn)
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private final int index; // 當(dāng)前執(zhí)行的過濾器索引
private final List<GatewayFilter> filters;
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
// 創(chuàng)建下一個鏈節(jié)點(diǎn)
DefaultGatewayFilterChain nextChain =
new DefaultGatewayFilterChain(this, this.index + 1);
// 執(zhí)行當(dāng)前過濾器,傳入下一個鏈節(jié)點(diǎn)
return filter.filter(exchange, nextChain);
}
return Mono.empty(); // 所有過濾器執(zhí)行完畢
});
}
}- 使用責(zé)任鏈模式,每個過濾器都可以決定是否繼續(xù)執(zhí)行下一個過濾器
- 通過遞歸創(chuàng)建鏈節(jié)點(diǎn)來實(shí)現(xiàn)
遞歸執(zhí)行過濾器
// 執(zhí)行流程(簡化版)
RateLimitFilter.filter(exchange, chain1)
-> 檢查限流
-> chain1.filter(exchange) // 調(diào)用下一個過濾器
-> AddRequestHeaderFilter.filter(exchange, chain2)
-> 添加請求頭
-> chain2.filter(exchange) // 調(diào)用下一個過濾器
-> LoadBalancerClientFilter.filter(exchange, chain3)
-> 負(fù)載均衡選擇實(shí)例
-> chain3.filter(exchange)
-> NettyRoutingFilter.filter(exchange, chain4)
-> 轉(zhuǎn)發(fā)請求到下游服務(wù)
-> chain4.filter(exchange)
-> NettyWriteResponseFilter.filter(exchange, chain5)
-> 寫入響應(yīng)
-> chain5.filter(exchange)
-> Mono.empty() // 所有過濾器執(zhí)行完畢- 每個過濾器調(diào)用
chain.filter(exchange)來執(zhí)行下一個過濾器 - 如果某個過濾器不想繼續(xù)執(zhí)行,可以不調(diào)用
chain.filter() - 比如限流過濾器,如果限流了,就直接返回錯誤,不繼續(xù)執(zhí)行
NettyRoutingFilter 作為最后一個過濾器,執(zhí)行實(shí)際的 HTTP 請求
// NettyRoutingFilter 的實(shí)現(xiàn)(簡化版)
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
// 使用 Reactor Netty HttpClient 發(fā)送請求(非阻塞)
return httpClient.get()
.uri(requestUrl)
.send((req, nettyOutbound) -> nettyOutbound.send(request.getBody()))
.responseConnection((res, connection) -> {
// 設(shè)置響應(yīng)到 Exchange
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
return Mono.just(res);
})
.then(chain.filter(exchange)); // 繼續(xù)執(zhí)行下一個過濾器
}NettyRoutingFilter使用 Reactor Netty 的HttpClient發(fā)送請求- 這是非阻塞的,線程不會在這里等待
- 響應(yīng)到達(dá)后,會繼續(xù)執(zhí)行下一個過濾器(
NettyWriteResponseFilter)
響應(yīng)通過 Mono 鏈?zhǔn)椒祷?/strong>
// 響應(yīng)返回流程
NettyWriteResponseFilter.filter(exchange, chain)
-> 寫入響應(yīng)到客戶端
-> Mono.empty() // 完成
-> 返回給 NettyRoutingFilter
-> 返回給 LoadBalancerClientFilter
-> 返回給 AddRequestHeaderFilter
-> 返回給 RateLimitFilter
-> 返回給 FilteringWebHandler
-> 返回給 RoutePredicateHandlerMapping
-> 返回給 DispatcherHandler
-> 返回給客戶端- 響應(yīng)通過 Mono 鏈?zhǔn)椒祷?/li>
- 每個過濾器都可以修改響應(yīng)
- 最終返回給客戶端
關(guān)鍵點(diǎn):
- 過濾器鏈?zhǔn)琼憫?yīng)式的,不會阻塞線程
- 每個過濾器都可以修改請求或響應(yīng)
- 過濾器可以決定是否繼續(xù)執(zhí)行下一個過濾器
NettyRoutingFilter是最后一個過濾器,負(fù)責(zé)實(shí)際轉(zhuǎn)發(fā)請求
2.4 響應(yīng)式 HTTP 請求
Flux<HttpClientResponse> responseFlux = httpClient
.headers(headers -> headers.add(httpHeaders))
.request(method)
.uri(url)
.send((req, nettyOutbound) -> nettyOutbound.send(request.getBody()))
.responseConnection((res, connection) -> {
// 處理響應(yīng)
return Mono.just(res);
});關(guān)鍵點(diǎn):
- 使用 Reactor Netty 的非阻塞 HTTP 客戶端
- 基于 Reactive Streams 的響應(yīng)式編程模型
- 支持背壓(Backpressure)控制
3. 實(shí)現(xiàn)關(guān)鍵點(diǎn)說明
3.1 響應(yīng)式編程模型
WebFlux 模式完全基于響應(yīng)式編程,使用 Project Reactor 的 Mono 和 Flux。這是 WebFlux 和 WebMVC 最根本的區(qū)別。
基本概念:
public interface GlobalFilter {
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}Mono 和 Flux 是什么?
Mono:表示 0 或 1 個元素的異步序列
Mono<String> name = Mono.just("Spring"); // 一個值
Mono<String> empty = Mono.empty(); // 0 個值
Mono<String> async = Mono.fromCallable(() -> {
// 異步操作
return fetchNameFromDatabase();
});Flux:表示 0 到 N 個元素的異步序列
Flux<String> names = Flux.just("Spring", "Cloud", "Gateway"); // 多個值
Flux<String> stream = Flux.interval(Duration.ofSeconds(1))
.map(i -> "Event " + i); // 無限流實(shí)際例子:
// WebMVC 方式(阻塞)
public ServerResponse handle(ServerRequest request) {
User user = userService.getUser(userId); // 阻塞等待
return ServerResponse.ok().body(user);
}
// WebFlux 方式(非阻塞)
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return userService.getUser(userId) // 返回 Mono<User>,不阻塞
.flatMap(user -> {
// 用戶數(shù)據(jù)到達(dá)后才執(zhí)行這里
exchange.getAttributes().put("user", user);
return chain.filter(exchange);
});
}優(yōu)勢說明:
非阻塞 I/O,提高并發(fā)性能
// 非阻塞調(diào)用下游服務(wù)
return httpClient.get()
.uri("http://backend-service/api/data")
.retrieve()
.bodyToMono(String.class) // 返回 Mono,不阻塞線程
.flatMap(data -> {
// 數(shù)據(jù)到達(dá)后才執(zhí)行這里
return processData(data);
});
// 在等待響應(yīng)的這段時間,線程可以處理其他請求- 線程不會阻塞,可以處理其他請求
- 一個線程可以處理多個請求
- 并發(fā)性能大幅提升
支持背壓,防止內(nèi)存溢出
// 背壓示例
Flux<String> dataStream = getDataStream(); // 數(shù)據(jù)流
dataStream
.limitRate(100) // 限制速率,防止內(nèi)存溢出
.subscribe(data -> {
// 處理數(shù)據(jù)
processData(data);
});- 如果生產(chǎn)者生產(chǎn)數(shù)據(jù)太快,消費(fèi)者可以告訴生產(chǎn)者慢一點(diǎn)
- 防止內(nèi)存溢出
- 這是 Reactive Streams 規(guī)范的核心特性
資源利用率高,少量線程處理大量請求
場景:處理 10000 并發(fā)請求 WebMVC: 需要 500 線程,內(nèi)存 ~500MB WebFlux: 只需要 16 線程,內(nèi)存 ~100MB 資源利用率提升 5 倍!
3.2 過濾器鏈模式
Gateway 使用責(zé)任鏈模式實(shí)現(xiàn)過濾器鏈。這是 Gateway 的核心設(shè)計(jì)模式之一。
責(zé)任鏈模式:
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private final int index; // 當(dāng)前過濾器索引
private final List<GatewayFilter> filters;
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
// 創(chuàng)建下一個鏈節(jié)點(diǎn)
DefaultGatewayFilterChain chain =
new DefaultGatewayFilterChain(this, this.index + 1);
// 執(zhí)行當(dāng)前過濾器,傳入下一個鏈節(jié)點(diǎn)
return filter.filter(exchange, chain);
}
return Mono.empty(); // 所有過濾器執(zhí)行完畢
});
}
}實(shí)際例子:
// 假設(shè)有這些過濾器
List<GatewayFilter> filters = [
RateLimitFilter, // index 0
AddRequestHeaderFilter, // index 1
NettyRoutingFilter // index 2
];
// 執(zhí)行流程
chain0.filter(exchange) // index = 0
-> RateLimitFilter.filter(exchange, chain1) // index = 1
-> 檢查限流
-> chain1.filter(exchange)
-> AddRequestHeaderFilter.filter(exchange, chain2) // index = 2
-> 添加請求頭
-> chain2.filter(exchange)
-> NettyRoutingFilter.filter(exchange, chain3) // index = 3
-> 轉(zhuǎn)發(fā)請求
-> chain3.filter(exchange)
-> index (3) >= filters.size(),返回 Mono.empty()過濾器類型:
GlobalFilter - 全局過濾器
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 這個過濾器會應(yīng)用于所有路由
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // 高優(yōu)先級
}
}- 應(yīng)用于所有路由
- 比如認(rèn)證、日志、監(jiān)控等
GatewayFilter - 路由過濾器
// 通過配置定義的路由過濾器
spring:
cloud:
gateway:
routes:
- id: user-service
filters:
- AddRequestHeader=X-User-Id, 123 # 路由過濾器- 只應(yīng)用于特定路由
- 通過配置文件或 API 定義
Ordered - 控制執(zhí)行順序
// 通過 Order 接口控制執(zhí)行順序
public class RateLimitFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return -100; // 數(shù)字越小,優(yōu)先級越高
}
}
public class LoggingFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return 1000; // 優(yōu)先級較低
}
}
// 執(zhí)行順序:RateLimitFilter (-100) -> LoggingFilter (1000)過濾器可以做什么?
修改請求
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest modifiedRequest = request.mutate()
.header("X-Request-Id", UUID.randomUUID().toString())
.build();
return chain.filter(exchange.mutate().request(modifiedRequest).build());
}
修改響應(yīng)
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("X-Response-Time",
String.valueOf(System.currentTimeMillis()));
}));
}
中斷執(zhí)行
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (isRateLimited(exchange)) {
// 限流了,直接返回錯誤,不繼續(xù)執(zhí)行
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange); // 繼續(xù)執(zhí)行
}
3.3 異步謂詞(AsyncPredicate)
路由匹配使用異步謂詞,支持異步條件判斷:
public interface AsyncPredicate<T> {
Mono<Boolean> test(T t);
}
支持的謂詞:
- Path Route Predicate
- Method Route Predicate
- Header Route Predicate
- Host Route Predicate
- Query Route Predicate
- RemoteAddr Route Predicate
- Weight Route Predicate
3.4 Netty 集成
使用 Reactor Netty 作為底層 HTTP 客戶端,提供高性能的非阻塞 I/O:
public class NettyRoutingFilter implements GlobalFilter {
private final HttpClient httpClient;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 使用 Reactor Netty HttpClient 發(fā)送請求
Flux<HttpClientResponse> responseFlux = httpClient
.request(method)
.uri(url)
.send(...)
.responseConnection(...);
}
}特性:
- 基于 Netty 的事件驅(qū)動模型
- 支持 HTTP/1.1 和 HTTP/2
- 支持 WebSocket
- 連接池管理
3.5 路由緩存
支持路由過濾器緩存,提高性能:
private final ConcurrentHashMap<Route, List<GatewayFilter>> routeFilterMap = new ConcurrentHashMap();
protected List<GatewayFilter> getCombinedFilters(Route route) {
if (this.routeFilterCacheEnabled) {
return routeFilterMap.computeIfAbsent(route, this::getAllFilters);
}
return getAllFilters(route);
}4. 總結(jié)說明
4.1 架構(gòu)特點(diǎn)
- 響應(yīng)式編程: 完全基于 Project Reactor 的響應(yīng)式編程模型
- 非阻塞 I/O: 使用 Reactor Netty 實(shí)現(xiàn)非阻塞 HTTP 通信
- 高并發(fā)性能: 少量線程處理大量并發(fā)請求
- 背壓支持: 支持 Reactive Streams 的背壓機(jī)制
4.2 適用場景
- 高并發(fā)、高吞吐量的 API 網(wǎng)關(guān)場景
- 需要處理大量長連接(如 WebSocket)
- 微服務(wù)架構(gòu)中的統(tǒng)一入口
- 需要流式處理(Streaming)的場景
4.3 關(guān)鍵優(yōu)勢
- 高性能: 非阻塞 I/O 提供更高的吞吐量
- 資源高效: 少量線程處理大量請求,資源利用率高
- 可擴(kuò)展性: 響應(yīng)式模型支持更好的水平擴(kuò)展
- 功能豐富: 支持 HTTP/2、WebSocket、gRPC 等協(xié)議
4.4 局限性
- 學(xué)習(xí)曲線: 需要理解響應(yīng)式編程模型
- 調(diào)試?yán)щy: 異步調(diào)用棧較難調(diào)試
- 阻塞風(fēng)險(xiǎn): 如果在響應(yīng)式鏈中執(zhí)行阻塞操作,會降低性能
- 內(nèi)存管理: 需要理解背壓機(jī)制,避免內(nèi)存問題
4.5 最佳實(shí)踐
- 避免阻塞操作: 不要在響應(yīng)式鏈中執(zhí)行阻塞 I/O
- 合理使用背壓: 理解背壓機(jī)制,合理配置緩沖區(qū)
- 監(jiān)控和指標(biāo): 使用 Spring Boot Actuator 監(jiān)控 Gateway 性能
- 過濾器順序: 合理設(shè)置過濾器順序,避免不必要的處理
到此這篇關(guān)于Spring Cloud Gateway WebFlux 模式架構(gòu)分析的文章就介紹到這了,更多相關(guān)Spring Cloud Gateway WebFlux 模式架構(gòu)分析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringCloud Webflux過濾器增加header傳遞方式
- SpringCloud Gateway之StripPrefix的使用方式
- SpringCloud Gateway 權(quán)限認(rèn)證的實(shí)現(xiàn)
- SpringCloud的網(wǎng)關(guān)Zuul和Gateway詳解
- Sentinel網(wǎng)關(guān)限流與SpringCloud Gateway整合過程
- springcloud gateway如何配置動態(tài)路由
- SpringCloud GateWay動態(tài)路由用法
- SpringCloud-Gateway網(wǎng)關(guān)的使用實(shí)例教程
相關(guān)文章
Java實(shí)現(xiàn)的并發(fā)任務(wù)處理實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)的并發(fā)任務(wù)處理方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了基于線程操作并發(fā)任務(wù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Java內(nèi)存模型(JMM)及happens-before原理
這篇文章主要介紹了java內(nèi)存模型(JMM)及happens-before原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
java使用TimerTask定時器獲取指定網(wǎng)絡(luò)數(shù)據(jù)
java.util.Timer定時器,實(shí)際上是個線程,定時調(diào)度所擁有的TimerTasks。一個TimerTask實(shí)際上就是一個擁有run方法的類,需要定時執(zhí)行的代碼放到run方法體內(nèi),TimerTask一般是以匿名類的方式創(chuàng)建,下面的就用示例來學(xué)習(xí)他的使用方法2014-01-01
SpringBoot?整合?Langchain4j?AIService?深度使用操作實(shí)戰(zhàn)教程
文章介紹LangChain4j中AIService組件,通過封裝大模型調(diào)用邏輯,簡化Java應(yīng)用對接LLM的流程,支持多模型切換、異步調(diào)用及@SystemMessage注解增強(qiáng)擴(kuò)展性,實(shí)現(xiàn)靈活的AI服務(wù)集成與調(diào)用,對SpringBoot?Langchain4j?AIService使用感興趣的朋友一起看看吧2025-07-07
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(12)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07
SpringCloud開啟session共享并存儲到Redis的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud開啟session共享并存儲到Redis的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02

