SpringCloudGateway网关实战(一)
目前对cloud的gateway功能还是不太熟悉,因此特意新建了对应的应用来尝试网关功能。
网关模块搭建
首先我们新建一个父模块用于添加对应的springboot依赖和cloud依赖。本模块我们的配置读取使用的是nacos,因此需要添加相关依赖。另外,由于SpringCloud新版本默认将Bootstrap禁用,因此我们需要添加对应的依赖才能使bootstrap.yml起作用。
父模块
父模块smallred-gateway依赖:
xml
<properties>
<spring-boot.version>2.7.13</spring-boot.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!-- bootstrap 启动器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
网关模块
网关模块gateway-api依赖:
xml
<dependencies>
<!-- SpringCloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
依赖pom文件创建完后,我们需要创建启动类和bootstrap.yml:
启动类:
java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
bootstrap.yml:
yaml
# Tomcat
server:
port: 8080
# Spring
spring:
application:
# 应用名称
name: gateway-api
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacosIP:8848
# 命名空间
namespace: nacos命名空间ID
config:
# 配置中心地址
server-addr: nacosIP:8848
# 命名空间
namespace: nacos命名空间ID
# 配置文件格式
file-extension: yaml
需要注意的是,我们需要在nacos中创建一个新的命名空间和在该命名空间中创建一个名为gateway-api的yaml配置文件。该文件暂时可以是这样空白的:
yaml
1
系统模块
这个模块用于模拟正常业务模块。
系统模块system-api依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringCloud Openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
依赖pom文件创建完后,我们需要创建启动类和bootstrap.yml:
启动类,这里需要加上服务发现注解@EnableDiscoveryClient:
java
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class SystemApplication {
public static void main(String[] args) {
SpringApplication.run(SystemApplication.class, args);
}
}
bootstrap.yml:
yaml
# Tomcat
server:
port: 9201
# Spring
spring:
application:
# 应用名称
name: system-api
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: nacosIP:8848
# 命名空间
namespace: nacos命名空间ID
config:
# 配置中心地址
server-addr: nacosIP:8848
# 命名空间
namespace: nacos命名空间ID
# 配置文件格式
file-extension: yaml
创建一个名称为system-api的配置文件,目前我们配置为空白即可:
yaml
1
创建一个接口用于测试使用:
java
@RestController
@RequestMapping("/system")
public class UserController {
@GetMapping(value = "/user/info")
public String getSystemInfo() {
return "欢迎来到系统模块";
}
}
路由配置
网关模块作为统一入口,那么就需要一个路由配置来给网关"指路"。
最常用的注册中心配置方式lb。注意这里的predicates是必填的,我们先如下进行填写。
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Path=/system-api/**
filters:
- StripPrefix=1
http地址配置方式
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: http://localhost:9201
predicates:
- Path=/system-api/**
filters:
- StripPrefix=1
websocket配置方式
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: ws://localhost:9201
predicates:
- Path=/system-api/**
filters:
- StripPrefix=1
这样,请求到
localhost:8080/system-api/system/user/info
这个接口时,就能成功请求了。
路由规则
讲完路由配置后,接下来我们就开始讲对应最多规则的路由规则。
DateTime
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- After=2023-08-20T22:20:00.000+08:00[Asia/Shanghai]
匹配日期时间之后发生的请求。如果在这个设定的时间之前,则报404
Cookie
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Cookie=loginname, smallred
匹配指定名称且其值与正则表达式匹配的cookie。如果不存在对应cookie,则报404
Header
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Header=X-Request-Id, \d+
当发送的请求头部中包含一个名为X-Request-Id
的字段,并且其值为一个或多个数字时,该请求就会匹配到这个路由规则。不含该Header,则报404
Host
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Host=**.somehost.org,**.anotherhost.org
任何以.somehost.org
或.anotherhost.org
作为后缀的域名都可以通过这个路由规则进行匹配。
Method
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Method=GET,POST
只有发送的请求使用了 GET 或 POST 方法时,才会匹配到这个路由规则。其他请求方法(如 PUT、DELETE 等)将不会被匹配。
Path
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Path=/system/**
只有发送的请求的路径以/system/
开头时,并且可以包含任意子路径,比如/system/user
、/system/settings
等,才会匹配到这个路由规则。
Query
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Query=username, abc.
只有发送的请求中包含一个名为username
且值为abc.
的查询参数时,才会匹配到这个路由规则。
RemoteAddr
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Cookie=loginname, smallred
只有发送的请求的远程地址为 192.168.10.1
或者属于 192.168.10.1/0
子网时,才会匹配到这个路由规则。
Weight
yaml
spring:
cloud:
gateway:
routes:
- id: system-api
uri: lb://system-api
predicates:
- Weight=group1, 8
- id: user-api
uri: lb://user-api
predicates:
- Weight=group1, 2
这两个路由规则示例都使用了权重(Weight)谓词来进行负载均衡,通过设置不同的权重值,可以控制转发给不同目标地址的请求的比例。在示例中,system-api被选中的概率更高,大约是user-api的四倍。
最简单的网关路由配置这里就结束了,下一章节我们讲讲更加深入的一些配置。