Spring Cloud Gateway之RouteLocator簡介
本文來自於openhome,點選標題見原文,Spring 5以後引入了Spring Cloud Gateway作為路由閘道器,類似Nginx,其複雜的路由規則可透過程式碼實現,這就是RouteLocator用處所在。
底下的RouteLocator可以將http:/localhost:5555/openhome/xxxx都路由到openhome.cc的網站:
package cc.openhome; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; @SpringBootApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } @Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p .predicate(exchange -> exchange.getRequest().getPath().subPath(0).toString().startsWith(("/openhome/"))) .filters(f -> f.rewritePath("/openhome/(?<remaining>.*)", "/${remaining}")) .uri("https://openhome.cc")) .build(); } } |
透過RouteLocatorBuilder的routes,可以逐一建立路由,每呼叫route一次可建立一條路由規則,p的代表是PredicateSpec,可以透過它的predicate來進行斷言,要實現的介面就是Java 8的Predicate,透過exchange取得了路徑,然後判斷它是不是以/openhome/開頭,對於簡單的情況,也可以透過PredicateSpec一些方法如path等來進行斷言。
filters是用來設定過濾器,rewritePath方法會使用內建的過濾器重寫路徑,實際上,也可以自行實現GatewayFilter例項,並透過filter方法來設定,例如同樣的功能,然而自定於GatewayFilter的話會是:
package cc.openhome; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.http.server.reactive.ServerHttpRequest; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; @SpringBootApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } @Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p .predicate(exchange -> exchange.getRequest().getPath().subPath(0).toString().startsWith(("/openhome/"))) .filters(f -> f.filter((exchange, chain) -> { ServerHttpRequest req = exchange.getRequest(); addOriginalRequestUrl(exchange, req.getURI()); String path = req.getURI().getRawPath(); String newPath = path.replaceAll("/openhome/(?<remaining>.*)", "/${remaining}"); ServerHttpRequest request = req.mutate() .path(newPath) .build(); exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI()); return chain.filter(exchange.mutate().request(request).build()); })) .uri("https://openhome.cc")) .build(); } } |
GatewayFilter 實際上只有一個方法要實現:
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
這感覺有點像是org.springframework.web.server.WebFilter對吧!事實上也是抄它的沒錯,GatewayFilter的原始碼註解中就這麼寫了:
/** * Contract for interception-style, chained processing of Web requests that may * be used to implement cross-cutting, application-agnostic requirements such * as security, timeouts, and others. Specific to a Gateway * * Copied from WebFilter * * @author Rossen Stoyanchev * @since 5.0 */ public interface GatewayFilter extends ShortcutConfigurable { |
在〈使用Spring Cloud Gateway〉中談過,Spring Cloud Gateway內建了一些斷言器與過濾器工廠類別,可以參考它們的實現,其中也包含了斷言器與過濾器的實現邏輯。
斷言器相關的原始碼可參考org/springframework/cloud/gateway/handler,過濾器相關的原始碼可參考org/springframework/cloud/gateway/filter。
例如,上面的範例中,GatewayFilter的實現就是從RewritePathGatewayFilterFactory中抄出來的。
透過Builder等方法,使用內建的斷言或過濾還是比較方便的,例如,相同的需求如下定義,還是比較方便的,例如路徑斷言可以透過path指定Ant路徑模式:
@Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p.path("/openhome/**") .filters(f -> f.rewritePath("/openhome/(?<remaining>.*)", "/${remaining}")) .uri("https://openhome.cc") ).build(); } |
底下是個能夠完成〈使用Spring Cloud Gateway〉相同路由的示範:
@Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p.path("/api/acct/**") .filters(f -> f.stripPrefix(2)) .uri("lb://acctsvi") ) .route(p -> p.path("/api/msg/**") .filters(f -> f.stripPrefix(2)) .uri("lb://msgsvi") ) .route(p -> p.path("/api/email/**") .filters(f -> f.stripPrefix(2)) .uri("lb://emailsvi") ) .build(); } |
相關文章
- Spring Cloud Gateway使用簡介SpringCloudGateway
- Spring cloud 之GatewaySpringCloudGateway
- spring cloud gateway之filter篇SpringCloudGatewayFilter
- spring cloud gateway 之限流篇SpringCloudGateway
- Spring Cloud Gateway 之 過濾器SpringCloudGateway過濾器
- Spring Cloud Gateway之負載均衡SpringCloudGateway負載
- spring Cloud Gateway 入門簡單使用SpringCloudGateway
- Spring Cloud Gateway + Nacos(1)簡單配置SpringCloudGateway
- Spring Cloud Gateway 深入SpringCloudGateway
- Spring Cloud Gateway示例 | DevGlanSpringCloudGatewaydev
- spring cloud gateway 不生效SpringCloudGateway
- Spring Cloud Gateway 限流操作SpringCloudGateway
- Spring Cloud Gateway 入門SpringCloudGateway
- Gateway 簡介Gateway
- spring cloud 簡單介紹SpringCloud
- Spring Cloud Gateway實戰之五:內建filterSpringCloudGatewayFilter
- 快速突擊 Spring Cloud GatewaySpringCloudGateway
- Spring Cloud Gateway初體驗SpringCloudGateway
- Spring Cloud Gateway 入門案例SpringCloudGateway
- Spring Cloud Gateway入坑記SpringCloudGateway
- Spring Cloud Gateway限流實戰SpringCloudGateway
- 介紹一下Spring Cloud簡介SpringCloud
- Spring Cloud Gateway 之 請求應答日誌列印SpringCloudGateway
- spring cloud gateway之服務註冊與發現SpringCloudGateway
- 2、Spring Cloud和dubbo簡介SpringCloud
- Spring Cloud Gateway 實現簡單自定義過濾器SpringCloudGateway過濾器
- Spring Cloud Gateway入門 - spring.ioSpringCloudGateway
- spring-cloud-gateway靜態路由SpringCloudGateway路由
- Spring Cloud Gateway WebFilter工廠 | BaeldungSpringCloudGatewayWebFilter
- Spring Cloud Gateway (一)入門篇SpringCloudGateway
- Spring Cloud Gateway---GlobalFilter(入門)SpringCloudGatewayFilter
- 阿里Sentinel支援Spring Cloud Gateway啦阿里SpringCloudGateway
- Spring Cloud Gateway限制API速率 - tanzuSpringCloudGatewayAPI
- Spring Cloud Gateway應用篇(十三)SpringCloudGateway
- 聊聊spring cloud gateway的XForwardedHeadersFilterSpringCloudGatewayForwardHeaderFilter
- spring cloud微服務分散式雲架構 - Spring Cloud簡介SpringCloud微服務分散式架構
- Spring Cloud Gateway實戰之四:內建predicate小結SpringCloudGateway
- Java之Spring Cloud概念介紹JavaSpringCloud