Spring Cloud 2025.0.0 Gateway迁移全过程详解

🧑 博主简介:CSDN博客专家历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程高并发设计Springboot和微服务,熟悉LinuxESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea

在这里插入图片描述

在这里插入图片描述


Spring Cloud 2025.0.0 Gateway迁移全过程详解

在这里插入图片描述

1. 引言

十分荣幸看到spring社区宣布 Spring Cloud 2025.0.0 Release Train 的正式发布 (GA) 现已推出。可以在 Maven Central 中找到该版本。有关更多信息,您可以查看 2025.0.0 发行说明。

当我们站在云原生技术演进的关键拐点,Spring Cloud 2025.0.0的发布标志着分布式系统开发范式的又一次重大突破。

这个版本并非简单的功能堆砌,而是针对现代微服务架构痛点进行的深度重构——它直面了传统Java应用在云原生环境中的性能瓶颈、安全脆弱性以及运维复杂性等核心挑战。

通过本次升级,开发团队将获得34%的启动速度跃升和25%的内存占用优化,这些数字背后是JVM底层机制的深度调优;安全层面对零信任架构的拥抱让服务间通信更值得信赖;

KubernetesGraalVM的深度集成则彻底打通了云原生落地的最后一公里。

本文重点介绍Gateway迁移过程中遇到的一些障碍及其正确处理方式!

2. Spring Cloud 2025.0.0网关新特性及其变化

  • 新增对 spring-cloud-functionspring-cloud-stream 处理程序的支持 #3646
  • 在服务器 webflux 中添加了对 Bucket4jRateLimiter 的支持 #2955
  • 弃用WebClientRouting基础设施。这将在今年晚些时候的 5.0 中删除。排名 #3680
  • 已创建新的 ModuleStarter 名称,旧名称已弃用。下表列出了新的和已弃用的构件 #3645。这些新名称阐明了两种类型的网关(服务器或代理交换)以及 Spring Framework 中的两个 Web 堆栈(Web MCVWebFlux)。使用已弃用的项目将在日志中添加一条警告消息。

2.1 依赖升级前后变化

Deprecated Artifact(废弃依赖)New Artifact(新版依赖)
spring-cloud-gateway-serverspring-cloud-gateway-server-webflux
spring-cloud-gateway-server-mvcspring-cloud-gateway-server-webmvc
spring-cloud-starter-gateway-serverspring-cloud-starter-gateway-server-webflux
spring-cloud-starter-gateway-server-mvcspring-cloud-starter-gateway-server-webmvc
spring-cloud-gateway-mvcspring-cloud-gateway-proxyexchange-webmvc
spring-cloud-gateway-webfluxspring-cloud-gateway-proxyexchange-webflux

2.2 配置前缀前后变化

迁移到新的属性前缀以匹配新的模块名称:#3361#3362#3363#3647。用spring-boot-properties-migrator支持已弃用的前缀。

下表列出了模块或启动器、其旧前缀新的替换前缀

Module/StarterDeprecated prefixNew prefix
spring-cloud-starter-gateway-server-webfluxspring.cloud.gateway.*spring.cloud.gateway.server.webflux.*
spring-cloud-starter-gateway-server-webmvcspring.cloud.gateway.mvc.*spring.cloud.gateway.server.webmvc.*
spring-cloud-gateway-proxyexchange-webfluxspring.cloud.gateway.proxy.*spring.cloud.gateway.proxy-exchange.webflux.*
spring-cloud-gateway-proxyexchange-webmvcspring.cloud.gateway.proxy.*spring.cloud.gateway.proxy-exchange.webmvc.*

2.3 重要核心类介绍

2.3.1 ReactiveLoadBalancerClientFilter

这是请求转发到其它微服务模块的负载均衡过滤器,GlobalFilter实现,使用反应式Spring Cloud LoadBalancer路由请求。

核心代码片段:

  1. 解析协议是否以lb://开头,是才会继续往下走
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
	return chain.filter(exchange);
}
  1. 解析出微服务的实例应用ID,为下一步获取具体的实例作铺垫:
URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String serviceId = requestUri.getHost();
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
	.getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
			RequestDataContext.class, ResponseData.class, ServiceInstance.class);
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(
		new RequestData(exchange.getRequest(), exchange.getAttributes()), getHint(serviceId)));

  1. 根据微服务应用实例ID获取应用列表的方法实现:
private Mono<Response<ServiceInstance>> choose(Request<RequestDataContext> lbRequest, String serviceId,
		Set<LoadBalancerLifecycle> supportedLifecycleProcessors) {
	ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance(serviceId,
			ReactorServiceInstanceLoadBalancer.class);
	if (loadBalancer == null) {
		throw new NotFoundException("No loadbalancer available for " + serviceId);
	}
	supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
	return loadBalancer.choose(lbRequest);
}
2.3.2 PathRoutePredicateFactory

这是配置转发微服务的路由规则的封装逻辑实现,网关就是通过这个类实现了自定义配置的方式识别请求应该被转发到哪个具体的微服务模块,若是没有匹配上,将走本网关的内部的资源请求。若仍然无法匹配,将返回404到客户端。

重要代码片段:

PathPattern match = null;
for (int i = 0; i < pathPatterns.size(); i++) {
	PathPattern pathPattern = pathPatterns.get(i);
	if (pathPattern.matches(path)) {
		match = pathPattern;
		break;
	}
}
2.3.3 GatewayDiscoveryClientAutoConfiguration

这是网关自动发现微服务模块并解析自动封装到转发配置规则里面的核心自动配置器。这个自动配置器最新核心的就是提供了两个模板,这两个模板用于将注册中心里面的服务实例匹配封装成转发规则,因此使用此类非常方便。

核心代码片段:

  1. 初始化转发规则模板(initPredicates),此部分很关键。这里是默认提供的模板,可以被自定义配置覆盖掉,后续会讲解。这个模板的意思是将从注册中心获取微服务实例,并将每类实例封装成各自路由转发规则
public static List<PredicateDefinition> initPredicates() {
	ArrayList<PredicateDefinition> definitions = new ArrayList<>();
	// TODO: add a predicate that matches the url at /serviceId?

	// add a predicate that matches the url at /serviceId/**
	PredicateDefinition predicate = new PredicateDefinition();
	predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
	predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
	definitions.add(predicate);
	return definitions;
}

以个人中心微服务为例,假设应用ID为personalhub,则通过此模板封装后的转发规则如下:

   # 个人中心微服务请求转发规则    
   - id: personalhub
     uri: lb://personalhub
     predicates: 
	     - name: Path
	       args: 
	         pattern: /personalhub/**

这样解释能理解吗?这是按Spring Cloud 2025.0.0 Gateway最新配置格式给大家展示的。

  1. 初始化模板过滤器,即initFilters,这个模板的意思是当转发规则匹配出需要的请求后,还需要经过这些初始化好的过滤器处理才能到达负载均衡执行。
public static List<FilterDefinition> initFilters() {
	ArrayList<FilterDefinition> definitions = new ArrayList<>();

	// add a filter that removes /serviceId by default
	FilterDefinition filter = new FilterDefinition();
	filter.setName(normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
	String regex = "'/' + serviceId + '/?(?<remaining>.*)'";
	String replacement = "'/${remaining}'";
	filter.addArg(REGEXP_KEY, regex);
	filter.addArg(REPLACEMENT_KEY, replacement);
	definitions.add(filter);

	return definitions;
}

默认情况下,该模板为每类微服务实例生成的过滤器是一个只是用于跳转处理的过滤器,比如当网关收到请求http://domain.com/personalhub/userid-1111时,先是经过上面的转发规则进行匹配,看是否满足规则所需,若是满足,则进入该规则对应的过滤器链进行处理。而此处的过滤器链,默认只有一个,只是用于将该请求跳转到personalhub的根路径上,如http://personalhub内网ip:端口/userid-1111,一般情况下其实用不着这个过滤器,因此如果向用自动配置转发规则的朋友,需要屏蔽掉该过滤器才行(下面会讲解如何屏蔽)。

3. Spring Cloud 2025.0.0网关配置迁移实操

这是本次版本迁移让人非常头疼的事情,变化太大了,出乎你的意料,很多配置项就算大肆查阅文档都很难查清楚,需要通过跟踪代码调试才能慢慢理解正确的配置方式。

3.1 删除旧的废弃依赖

以下依赖是本次新版本所 废弃 的,需要去除:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

3.2 引入新版依赖

<dependencyManagement>
    <dependencies>
			<dependency>
			    <groupId>org.springframework.cloud</groupId>
			    <artifactId>spring-cloud-dependencies</artifactId>
			    <version>2025.0.0</version>
			    <type>pom</type>
			    <scope>import</scope>
			</dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
	  <dependency>
		    <groupId>org.springframework.cloud</groupId>
		    <artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
		    <version>4.3.0</version>
		</dependency>
</dependencies>

3.3 网关手动配置转发规则受体(GatewayProperties)

就是手动为每一个微服务路由转发配置,这些配置最终会封装到一个叫GatewayProperties的配置对象中,我们通过观察此对象,就可以清晰地知道对应的yml应该如何配置了。

  1. GatewayProperties相关属性代码,针对yml配置前缀spring.cloud.gateway.server.webflux进行属性自动封装。
public class GatewayProperties {

	/**
	 * 属性前缀,Properties prefix.
	 */
	public static final String PREFIX = "spring.cloud.gateway.server.webflux";

	/**
	 *路由转发规则
	 */
	@NotNull
	@Valid
	private List<RouteDefinition> routes = new ArrayList<>();

	/**
	 * 公共默认过滤器,所有匹配出的请求都会经过这些过滤器处理
	 */
	private List<FilterDefinition> defaultFilters = new ArrayList<>();
  1. 路由定义受体RouteDefinition
public class RouteDefinition {

	private String id;

	// 匹配规则配置
	private List<PredicateDefinition> predicates = new ArrayList<>();

	// 匹配成功后需要经过哪些过滤器处理
	private List<FilterDefinition> filters = new ArrayList<>();

  // 路由转发规则而顺序
	private int order = 0;

   // 是否启用该路由转发规则
	private boolean enabled = true;
  1. 路由匹配规则受体PredicateDefinition
public class PredicateDefinition {

	// 规则名称
	private String name;

    // 规则参数
	private Map<String, String> args = new LinkedHashMap<>();

3.4 网关自动配置转发规则受体(DiscoveryLocatorProperties

上面3.3小节是针对手动配置微服务实例路由匹配转发规则的讲解。

这部分是针对喜欢用自动配置路由转发规则的朋友单独介绍。即自动从注册中心发现里面有哪些可用的微服务实例,全部读取下来自动封装成对应的路由匹配转发规则。

自动配置这部分,系统默认提供了前面介绍的两个模板,一个匹配规则模板,一个过滤器处理模板

这两个模板只是默认的,其实可以通过yml配置去覆盖,配置前缀为“spring.cloud.gateway.server.webflux.discovery.locator”,这些配置将会封装到DiscoveryLocatorProperties对象中。

@ConfigurationProperties("spring.cloud.gateway.server.webflux.discovery.locator")
public class DiscoveryLocatorProperties {

	/** 是否启用自动配置,这个是总开关 */
	private boolean enabled = false;

	/**
	 * SpEL 表达式,用于为每注册中心每类实例自动按该表达式模板创建一个匹配规则。这里是默认值。
	 */
	private String urlExpression = "'lb://'+serviceId";

	/**
	 * 是否全部转换为小写进行匹配,默认false
	 */
	private boolean lowerCaseServiceId = false;

3.5 手动配置微服务路由转发规则

手动配置转发规则,就是手动为每个需要网关转发请求过去的微服务实例,配置一个路由转发规则,在Spring Cloud 2025.0.0 Gateway新版本中,配置格式如下:

spring.cloud.gateway.server.webflux: 
  routes: 
     # websocket转发
    - id: im
      uri: lb://im
      predicates: 
        - name: Path
          args: 
            pattern: /im/**
        
    # 个人中心转发
    - id: personalhub
      uri: lb://personalhub
      predicates: 
        - name: Path
          args: 
            pattern: /personalhub/**
        
    # 商城请求转发
    - id: mall
      uri: lb://mall
      predicates: 
        - name: Path
          args: 
            pattern: /mall/**

3.6 自动配置微服务路由转发规则

从微服务注册中心获取所有实例类目,然后自动封装成每类实例的路由匹配转发规则

spring.cloud.gateway.server.webflux.discovery.locator: 
  
  # 是否启用,注意这是全局自动配置的开关。
  enabled: true
      
      # 控制服务名小写
      lowerCaseServiceId: true
      urlExpression: "'lb://'+serviceId"
      predicates: 
        - name: Path
          args: 
            
            # 以spring.webApiPrefix为前缀(如spring.webApiPrefix=/api/v2)
            pattern: "'${spring.webApiPrefix:}/'+serviceId+'/**'"
      
      # 如果discovery.locator.enabled=true,就一定要配置这个,否则默认行为会将请求路径进行重写,具体代码在GatewayDiscoveryClientAutoConfiguration配置中
      filters: 

4 总结

以上就是本次最新版本Spring Cloud 2025.0.0 Gateway迁移踩坑全过程详解。大家看懂了吗?

Spring Cloud 2025.0.0不仅是一次技术升级,更是开发范式的转型。

通过深度整合云原生生态的核心技术栈,它解决了Java微服务在云原生时代的三大核心矛盾:性能与资源效率的平衡、安全与易用性的统一、开发体验与运维复杂性的博弈。这些改进并非实验室中的理想化方案,而是经过大规模商业实践验证的可靠架构。

随着GraalVM等技术的持续成熟,我们有理由相信Java在云原生领域将迎来新的黄金时代。

评论 89
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码到π退休

你的打赏是我精心创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值