本文基于JDK8+SpringBoot2.7.18进行实践
一、引入pom依赖
- 在gateway模块的pom中引入gateway相关依赖,如下:
<!-- 引入 Spring Cloud Gateway 相关依赖,使用它作为网关,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
二、配置gateway路由
- 在gateway模块的application.yaml文件中定义路由规则, 这里定义了三个微服务的路由,如下:
server:
port: 30000
spring:
application:
name: gateway-application
cloud:
# Spring Cloud Gateway 配置项,对应 GatewayProperties 类
gateway:
# 路由配置项,对应 RouteDefinition 数组
routes:
- id: Service1 # 路由的ID,没有固定规则但要求唯一,建议配成微服务名
uri: http://localhost:8081 # 路由到Service1的目标地址
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/user
# filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组
# - StripPrefix=1 #去掉一级前缀
- id: Service2 # 路由的ID,没有固定规则但要求唯一,建议配成微服务名
uri: http://localhost:8082 # 路由到Service2的目标地址
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/product
- id: Service3 # 路由的ID,没有固定规则但要求唯一,建议配成微服务名
uri: http://localhost:8083 # 路由到Service3的目标地址
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/order
main:
web-application-type: reactive # 使用 Spring Cloud Gateway,应该使用Spring WebFlux而不是Spring MVC,这意味着需要将项目配置为使用响应式编程模型
三、三个微服务中分别定义路由中配置的测试接口
- Service1
@GetMapping("/user")
public String getUser(){
return "I am Service1";
}
- Service2
@GetMapping("/product")
public String getProduct(){
return "I am Service2";
}
- Service3
@GetMapping("/order")
public String getOrder(){
return "I am Service3";
}
四、分别启动四个服务
五、测试代理
六、遇到的坑
- Q1: 引入gateway依赖后启动报错,报错信息:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway. Action: Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
- 问题分析
项目中同时包含了 Spring MVC 和 Spring Cloud Gateway,这是不兼容的。Spring Cloud Gateway 是基于 Spring WebFlux 构建的,而 Spring MVC 是基于 Spring Web 的。它们在处理请求和响应的方式上有所不同,因此不能同时使用。
- 解决方法
-
第一、gateway模块中删除以下web依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
第二、设置gateway模块为使用响应式编程模型
在gateway模块的application.yaml文件中配置web-application-type,如下:
main: web-application-type: reactive # 使用 Spring Cloud Gateway,应该使用Spring WebFlux而不是Spring MVC,这意味着需要将项目配置为使用响应式编程模型
-
- 问题分析
- Q2: mac m1 gateway 报错:
Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'.
-
问题分析
出现这个问题是因为我本机为m1芯片的mac电脑,在安装使用了spring-cloud-starter-gateway依赖之后需要额外安装netty-resolver-dns-native-macos依赖
-
解决方法
在gateway模块的pom中添加如下依赖即可:
<!-- 解决mac m1 io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider 问题 --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-resolver-dns-native-macos</artifactId> <scope>runtime</scope> <classifier>osx-aarch_64</classifier> </dependency>
-