免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

第18课:Gateway路由规则、内置谓词、自定义谓词实战

第18课:Gateway路由规则、内置谓词、自定义谓词实战 文章目录一、开篇路由是网关的“灵魂”二、路由配置的两种方式2.1 2025版配置前缀变更必读2.2 快捷配置 vs 完全展开三、内置谓词工厂详解3.1 Path谓词最常用3.2 Method谓词3.3 Header谓词3.4 Query谓词3.5 Cookie谓词3.6 Host谓词3.7 时间类谓词After / Before / Between3.8 RemoteAddr谓词3.9 Weight谓词权重路由四、路径重写与灰度路由实战4.1 RewritePath路径重写4.2 灰度路由完整实战五、自定义谓词工厂实战5.1 核心实现步骤5.2 实战VIP用户灰度谓词工厂5.3 配置使用5.4 自定义谓词不生效的常见原因六、踩坑指南坑一配置前缀未迁移导致路由静默失效坑二Path谓词正则表达式不匹配多级路径坑三Weight权重路由不生效坑四自定义谓词类名不规范导致配置解析失败坑五灰度路由order值配置错误七、课后作业八、下节预告《最新版 SpringCloud 2025 从入门到实战》系列课程导航适配版本Spring Cloud Gateway 5.0.0、Spring Cloud 2025.1.3Oakwood、Spring Boot 4.0.8、Spring Cloud Alibaba 2025.1.0.0、JDK 21课程定位网关核心能力实战从路由配置到内置谓词从路径重写到自定义谓词工厂掌握路由规则的全部关键点一、开篇路由是网关的“灵魂”第17课我们完成了Gateway的架构认知理解了Reactor-Netty异步原理梳理了请求五阶段流转链路掌握了2025版双栈架构和配置前缀变更。现在进入Gateway最核心的能力——路由。路由解决的是一个基本问题什么样的请求转发到哪个服务。看起来简单实则不然。真实的业务场景中路由规则往往非常复杂只有携带特定Header的灰度用户才路由到新版本只有来自内网IP的请求才允许访问管理接口只在秒杀时间段内才路由到秒杀服务不同App版本的用户路由到不同后端。这些问题都需要通过谓词Predicate来精细控制。Gateway内置了十余种谓词工厂覆盖路径、方法、Header、Cookie、时间、权重、远程地址等几乎所有HTTP请求属性。当内置谓词无法满足需求时还可以自定义谓词工厂。本课将从路由配置的基础讲起逐一剖析内置谓词的用法实战路径重写、权重路由和灰度路由最后手把手教你实现自定义谓词工厂。需要特别注意的是Gateway 5.0的配置前缀发生了根本性变更沿用旧前缀会导致路由完全不生效——这是本课第一个必须掌握的知识点。二、路由配置的两种方式2.1 2025版配置前缀变更必读在动手配置路由之前必须确认一件事配置前缀已经变了。版本配置前缀Gateway 4.x旧spring.cloud.gateway.*Gateway 5.x新spring.cloud.gateway.server.webflux.*源码中GatewayProperties.PREFIX的值已变更为spring.cloud.gateway.server.webflux。如果不迁移前缀路由配置静默不生效——启动不会报错但访问时返回404日志中只有No RouteDefinition found。旧写法Gateway 5.x不认# ❌ 无效配置spring:cloud:gateway:routes:-id:user_routeuri:lb://service-user新写法Gateway 5.x正确# ✅ 正确配置spring:cloud:gateway:server:webflux:routes:-id:user_routeuri:lb://service-userpredicates:-Path/api/user/**踩坑提示可以临时引入spring-boot-properties-migrator来兼容旧前缀但建议立即迁移到新前缀。旧前缀将在未来版本中彻底移除。2.2 快捷配置 vs 完全展开Gateway提供了两种谓词配置方式快捷方式和完全展开方式。快捷配置通过谓词名称识别后跟等号再跟逗号分隔的参数值spring:cloud:gateway:server:webflux:routes:-id:user_routeuri:lb://service-userpredicates:-Path/api/user/**-MethodGET完全展开的参数更接近标准YAML使用name和args键值对spring:cloud:gateway:server:webflux:routes:-id:user_routeuri:lb://service-userpredicates:-name:Pathargs:patterns:/api/user/**-name:Methodargs:methods:GET两种方式的选型建议简单谓词用快捷方式配置简洁复杂谓词如多个Path模式、带正则的参数用完全展开方式避免逗号分隔导致的歧义。三、内置谓词工厂详解Spring Cloud Gateway内置了十余种路由谓词工厂所有谓词都与HTTP请求的不同属性匹配多个谓词之间通过AND逻辑组合——请求必须同时满足所有谓词条件才会被路由。3.1 Path谓词最常用匹配请求路径模式是日常开发中使用频率最高的谓词。predicates:-Path/api/user/**-Path/api/order/**,/api/payment/**Path谓词支持/**通配符和{segment}路径变量。如果需要更灵活的正则匹配如匹配任意层级路径可以自定义AntPathRoutePredicateFactory使用AntPathMatcher替代默认的PathPatternParser。3.2 Method谓词匹配HTTP请求方法predicates:-MethodGET,POST3.3 Header谓词匹配请求头中的参数名和值支持正则表达式predicates:-HeaderX-Request-Id,\d-HeaderAuthorization,Bearer.*典型应用场景灰度路由——只有携带X-Gray-Version: v2的请求才路由到新版本服务。3.4 Query谓词匹配URL查询参数predicates:-Queryname,Jack-Querydebug第二个参数为正则表达式不填写时表示只要存在该参数即匹配。3.5 Cookie谓词匹配请求Cookiepredicates:-CookieJSESSIONID,[a-z0-9]3.6 Host谓词匹配请求Host头predicates:-Host**.example.com3.7 时间类谓词After / Before / Between基于请求时间进行匹配常用于限时活动场景predicates:# 2030年1月20日之后才路由-After2030-01-20T17:42:47.789-07:00[America/Denver]# 秒杀时间段内才路由-Between2026-11-11T00:00:0008:00[Asia/Shanghai],2026-11-11T23:59:5908:00[Asia/Shanghai]时间格式为ZonedDateTime可用System.out.println(ZonedDateTime.now())打印当前时区格式。3.8 RemoteAddr谓词匹配客户端IP地址支持CIDR格式predicates:-RemoteAddr192.168.1.1/24典型应用场景只有内网IP才能访问管理接口。3.9 Weight谓词权重路由Weight谓词用于灰度发布根据权重将流量分配到不同版本的服务实例。同一分组内的所有路由权重之和应为100spring:cloud:gateway:server:webflux:routes:-id:user_v1uri:lb://service-user-v1predicates:-Path/api/user/**-Weightuser-group,95-id:user_v2uri:lb://service-user-v2predicates:-Path/api/user/**-Weightuser-group,5上述配置将95%的流量路由到v1版本5%路由到v2版本。灰度验证通过后逐步调整权重直至v2全量。四、路径重写与灰度路由实战4.1 RewritePath路径重写路径重写用于将外部暴露的URL路径转换为后端服务实际接收的路径。例如前端调用/api/user/1后端服务实际接收/user/1去掉/api前缀spring:cloud:gateway:server:webflux:routes:-id:user_routeuri:lb://service-userpredicates:-Path/api/user/**filters:-RewritePath/api/user/(?segment.*),/user/${segment}正则命名捕获组(?segment.*)捕获/api/user/之后的所有内容${segment}在替换表达式中引用该值。4.2 灰度路由完整实战灰度路由的核心思想是通过请求特征识别灰度用户将灰度用户路由到新版本。方案一基于Header的灰度路由spring:cloud:gateway:server:webflux:routes:-id:user_grayuri:lb://service-user-v2predicates:-Path/api/user/**-HeaderX-Gray-Version,v2-id:user_normaluri:lb://service-user-v1predicates:-Path/api/user/**order:10# order越小优先级越高正常路由作为兜底关键规则灰度路由的order值应小于正常路由的order值确保灰度请求优先匹配。未携带灰度Header的请求自动落入正常路由。方案二基于权重的灰度路由如前文3.9节所示通过Weight谓词按比例分配流量适合“不区分用户只按比例灰度”的场景。方案三基于Cookie的灰度路由predicates:-Path/api/user/**-Cookiegray,true方案四组合条件灰度路由实际生产中灰度规则往往是组合的。例如内网用户 特定App版本才路由到新版本predicates:-Path/api/user/**-RemoteAddr192.168.1.0/24-HeaderX-App-Version,2\.0\..*五、自定义谓词工厂实战当内置谓词无法满足复杂业务需求时如需要查询数据库、解析JWT、判断用户VIP等级需要实现自定义谓词工厂。5.1 核心实现步骤实现自定义谓词工厂需要四步步骤一继承AbstractRoutePredicateFactoryConfig。步骤二定义静态内部类Config用于接收YAML中的配置参数。步骤三实现apply(Config)方法返回一个PredicateServerWebExchange。步骤四覆盖shortcutFieldOrder()方法可选但推荐定义快捷配置的字段顺序。5.2 实战VIP用户灰度谓词工厂需求根据请求头中的用户等级只有VIP用户才路由到新版本服务。packagecom.example.microservice.gateway.predicate;importorg.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;importorg.springframework.stereotype.Component;importorg.springframework.web.server.ServerWebExchange;importjava.util.List;importjava.util.function.Predicate;ComponentpublicclassVipRoutePredicateFactoryextendsAbstractRoutePredicateFactoryVipRoutePredicateFactory.Config{publicVipRoutePredicateFactory(){super(Config.class);}OverridepublicListStringshortcutFieldOrder(){returnList.of(level);}OverridepublicPredicateServerWebExchangeapply(Configconfig){returnexchange-{StringuserLevelexchange.getRequest().getHeaders().getFirst(X-User-Level);if(userLevelnull){returnfalse;}// 比较用户等级是否达到要求如 GOLD 匹配 GOLD 和 DIAMONDreturncompareLevel(userLevel,config.getLevel());};}privatebooleancompareLevel(Stringactual,Stringrequired){ListStringlevelsList.of(NORMAL,SILVER,GOLD,DIAMOND);intactualIdxlevels.indexOf(actual.toUpperCase());intrequiredIdxlevels.indexOf(required.toUpperCase());returnactualIdxrequiredIdxrequiredIdx0;}ValidatedpublicstaticclassConfig{privateStringlevel;publicStringgetLevel(){returnlevel;}publicvoidsetLevel(Stringlevel){this.levellevel;}}}关键规范类名必须以RoutePredicateFactory结尾如VipRoutePredicateFactory谓词名称对应类名前缀VipRoutePredicateFactory→ 配置中使用VipshortcutFieldOrder()返回的字段顺序决定了快捷配置中参数的顺序5.3 配置使用spring:cloud:gateway:server:webflux:routes:-id:user_vip_grayuri:lb://service-user-v2predicates:-Path/api/user/**-VipGOLD快捷配置VipGOLD会将GOLD自动映射到Config.level字段。完全展开配置predicates:-name:Vipargs:level:GOLD5.4 自定义谓词不生效的常见原因问题原因解决谓词完全未匹配未注册为Spring Bean添加Component注解配置解析失败类名未以RoutePredicateFactory结尾遵循命名规范参数值未注入未覆盖shortcutFieldOrder()实现该方法并返回字段列表匹配逻辑异常apply()中抛出异常添加空值检查和异常捕获六、踩坑指南坑一配置前缀未迁移导致路由静默失效现象启动无报错但所有路由返回404日志中只有No RouteDefinition found。原因使用了旧的spring.cloud.gateway.routes前缀而Gateway 5.x要求spring.cloud.gateway.server.webflux.routes。解决迁移到新前缀或临时引入spring-boot-properties-migrator兼容。这个问题没有任何报错提示是最隐蔽的坑必须第一优先级排查。坑二Path谓词正则表达式不匹配多级路径现象Path/(.*)/test-file.js无法匹配/segment1/segment2/test-file.js。原因Gateway 5.x默认使用PathPatternParser不支持任意层级正则匹配。解决自定义AntPathRoutePredicateFactory使用AntPathMatcher替代配置AntPath/**/test-file.js。坑三Weight权重路由不生效现象配置了Weight谓词但流量仍然全部路由到一个版本。原因同一分组内的路由必须同时配置Weight谓词且权重之和为100。如果只有一个路由配置了Weight流量会全部走该路由。解决确保同一WeightgroupName, weight分组下所有路由都配置了Weight谓词。坑四自定义谓词类名不规范导致配置解析失败现象自定义谓词在YAML中配置后启动报错Unable to find RoutePredicateFactory with name Vip。原因类名未以RoutePredicateFactory结尾Gateway无法从类名推断谓词名称。解决将类名规范为{谓词名}RoutePredicateFactory的格式。坑五灰度路由order值配置错误现象灰度请求也被路由到了正常版本。原因灰度路由的order值大于正常路由导致正常路由先匹配。解决灰度路由的order值应小于正常路由。order越小优先级越高默认值为0。七、课后作业作业一配置三条路由规则/api/user/**路由到service-user/api/order/**路由到service-order/api/product/**路由到service-product。验证通过网关访问三个服务的接口。作业二配置一条灰度路由携带X-Gray-Version: v2Header的请求路由到service-user-v2其他请求路由到service-user-v1。使用curl验证两条路由的匹配结果。作业三配置Weight权重路由将service-user的95%流量路由到v1实例5%路由到v2实例。通过多次调用观察流量分布。作业四进阶实现一个自定义谓词工厂TimeBetweenRoutePredicateFactory支持配置时间段如09:00-18:00只有当前时间在该时间段内的请求才路由。在秒杀场景中使用该谓词。八、下节预告第19课将进入Gateway过滤器、全局拦截、请求响应统一处理。内容包括局部过滤器与全局过滤器的区别、执行顺序控制、跨域统一配置、请求参数校验、响应结果统一封装、异常统一拦截和日志全局打印。本课完成了路由规则的深度实战路由决定了“请求去哪里”第19课的过滤器将决定“请求经过网关时做什么”——鉴权、日志、参数修改、响应增强这些跨切面关注点都将在过滤器中实现。《最新版 SpringCloud 2025 从入门到实战》系列课程导航去订阅第一部分微服务前置基础 新版环境搭建第1-5课第二部分注册中心核心Nacos 最新版第6-9课第三部分配置中心核心Nacos配置中心第10-12课第四部分服务通信核心OpenFeign LoadBalancer第13-16课第五部分网关核心SpringCloud Gateway 新版第17-20课第六部分熔断、限流、降级Sentinel 新版第21-24课第七部分微服务监控、链路追踪、日志体系第25-28课第八部分微服务高阶特性 分布式核心能力第29-31课第九部分企业级完整项目实战 架构复盘第32-35课
返回列表