搭建基本框架

项目结构

image-20220412085504882

创建父项目

作用

创建一个父项目(Maven项目,可以把src文件夹删除掉),其作用是用于管理依赖的版本号以及子项目模块

创建过程

pom.xml的内容如下:(modules节点的内容不用管,这是由IntelliJ IDEA自动生成用于管理子项目模块的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.ledao</groupId>
<artifactId>GatewayDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>order</module>
<module>stock</module>
<module>gateway</module>
<module>common</module>
</modules>
<packaging>pom</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<springboot.version>2.3.2.RELEASE</springboot.version>
<springcloudalibaba.version>2.2.6.RELEASE</springcloudalibaba.version>
<common.version>1.0-SNAPSHOT</common.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${springcloudalibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.ledao</groupId>
<artifactId>common</artifactId>
<version>${common.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

创建公共项目

作用

创建一个公共项目(Maven项目),用于管理公共依赖、工具类以及实体类等

创建过程

pom.xml的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>GatewayDemo</artifactId>
<groupId>com.ledao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>common</artifactId>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

创建订单项目

作用

创建一个订单项目模块,模拟真实业务,用于测试

创建过程

pom.xml的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>GatewayDemo</artifactId>
<groupId>com.ledao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>order</artifactId>

<dependencies>
<dependency>
<groupId>com.ledao</groupId>
<artifactId>common</artifactId>
</dependency>
</dependencies>
</project>

application.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
server:
port: 8081
servlet:
context-path: /
tomcat:
uri-encoding: utf-8

spring:
application:
name: order
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss

新建启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.ledao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author LeDao
* @company
* @create 2022-04-11 23:19
*/
@SpringBootApplication
public class OrderApplication {

public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}

控制层,通过http://localhost:8081/order/test访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.ledao.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
* @author LeDao
* @company
* @create 2022-04-11 23:17
*/
@RestController
@RequestMapping("/order")
public class OrderController {

@RequestMapping("/test")
public Map<String, Object> test() {
Map<String, Object> resultMap = new HashMap<>(16);
resultMap.put("模块名称", "订单模块");
resultMap.put("请求时间", new Date());
return resultMap;
}
}

创建库存项目

作用

创建一个库存项目模块,模拟真实业务,用于测试

创建过程

pom.xml的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>GatewayDemo</artifactId>
<groupId>com.ledao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>stock</artifactId>

<dependencies>
<dependency>
<groupId>com.ledao</groupId>
<artifactId>common</artifactId>
</dependency>
</dependencies>
</project>

application.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
server:
port: 8082
servlet:
context-path: /
tomcat:
uri-encoding: utf-8

spring:
application:
name: stock
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss

新建启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.ledao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author LeDao
* @company
* @create 2022-04-11 23:22
*/
@SpringBootApplication
public class StockApplication {

public static void main(String[] args) {
SpringApplication.run(StockApplication.class, args);
}
}

控制层,通过http://localhost:8082/stock/test访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.ledao.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
* @author LeDao
* @company
* @create 2022-04-11 23:23
*/
@RestController
@RequestMapping("/stock")
public class StockController {

@RequestMapping("/test")
public Map<String, Object> test() {
Map<String, Object> resultMap = new HashMap<>(16);
resultMap.put("模块名称", "库存模块");
resultMap.put("请求时间", new Date());
return resultMap;
}
}

测试

启动订单项目和库存项目

通过http://localhost:8081/order/test访问,返回:

1
{"模块名称":"订单模块","请求时间":"2022-04-14 11:25:51"}

通过http://localhost:8082/stock/test访问,返回:

1
{"模块名称":"库存模块","请求时间":"2022-04-14 11:25:49"}

出现上面结果说明搭建成功

开始使用Gateway

实现访问其它项目接口

首先创建Gateway项目模块,pom.xml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>GatewayDemo</artifactId>
<groupId>com.ledao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>gateway</artifactId>

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

application.yml配置文件如下,使用spring.cloud.gateway.routes配置

id:路由id,设置为被访问项目的名称

uri:路由地址,设置为被访问项目的端口

predicates:断言规则,设置为被访问项目的请求路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server:
port: 8080
servlet:
context-path: /
tomcat:
uri-encoding: utf-8

spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**

- id: stock
uri: http://localhost:8082/
predicates:
- Path=/stock/**

启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.ledao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author LeDao
* @company
* @create 2022-04-11 23:35
*/
@SpringBootApplication
public class GatewayApplication {

public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}

测试

启动Gateway网关项目

通过http://localhost:8080/order/test访问,返回:

1
{"模块名称":"订单模块","请求时间":"2022-04-14 11:25:51"}

通过http://localhost:8080/stock/test访问,返回:

1
{"模块名称":"库存模块","请求时间":"2022-04-14 11:25:49"}

出现上面结果说明已经成功,其中8080为Gateway网关项目的端口

路由匹配规则

匹配指定日期之后的请求After

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- After=2022-04-14T13:12:12+08:00[Asia/Shanghai]

匹配指定日期之前的请求Before

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Before=2022-04-14T11:12:00+08:00[Asia/Shanghai]

匹配两个指定日期之间的请求Between

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Between=2022-04-14T13:12:00+08:00[Asia/Shanghai],2022-04-14T14:12:00+08:00[Asia/Shanghai]

Cookie路由匹配规则Cookie,下面配置中token是名称,\d+为值的匹配规则(只包含数字,1个或多个)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Cookie=token, \d+

Header路由匹配规则Header,下面配置中X-Request-Id是名称,\d+的说明看上面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Header=X-Request-Id, \d+

Host路由匹配规则,规定只有指定域名才能访问接口,下面配置了mytest.commytest2.com两个域名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Host=**.mytest.com,**.mytest2.com

Method路由匹配规则,下面只匹配GET请求,如果是POST请求就不能访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Method=GET

path路由匹配规则,根据请求路径匹配

一些匹配示例说明如下:

  1. /order/**:以/order/开头的请求路径
  2. /order/my/{aa}/order/my/test可以通过,/order/test/order/my/ss/test不可以通过
1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**

Query路由匹配规则,请求时需要带指定参数(值可为空),下面配置中需要带name参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
- Query=name

内置过滤器

AddRequestParameter

向请求接口传递参数,格式为AddRequestParameter=name,ledao,name为参数名,ledao为值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- AddRequestParameter=name,ledao

RewritePath

用于实现URL重写,下面的配置会把/gateway/order/test重写成/order/test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/gateway/**
filters:
- RewritePath=/gateway(?<segment>/?.*), $\{segment}

SetStatus

设置返回的结果状态码,下面的配置返回404,HTTP常见状态码查看:http常见状态码有哪些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- SetStatus=404

效果截图

image-20220417122637663

AddResponseHeader

返回信息添加Header头信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- AddResponseHeader=X-Response-Author,LeDao

结果截图

image-20220417124138292

更多

查看:Spring Cloud Gateway

自定义GatewayFilter

要先把application.yml的Gateway配置删除,然后新建MyGatewayFilter类实现GatewayFilter、Ordered接口重写filter和getOrder方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.ledao.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
* @author LeDao
* @company
* @create 2022-04-17 13:01
*/
public class MyGatewayFilter implements GatewayFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("我的自定义网关过滤器");
//获取请求的参数name的值
System.out.println(exchange.getRequest().getQueryParams().get("name"));
return chain.filter(exchange);
}

@Override
public int getOrder() {
//越小优先级越高
return -1;
}
}

新建MyGatewayFilterConfig配置类注册Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.ledao.config;

import com.ledao.filter.MyGatewayFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @author LeDao
* @company
* @create 2022-04-17 13:05
*/
@Configuration
public class MyGatewayFilterConfig {

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes().route(r -> r
.path("/order/**")
.uri("http://localhost:8081/")
.filter(new MyGatewayFilter())
.id("myGatewayFilter")
).build();
}
}

自定义GlobalFilter

新建MyGlobalFilter类实现GlobalFilter、Ordered接口重写filter和getOrder方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.ledao.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
* @author LeDao
* @company
* @create 2022-04-17 13:50
*/
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("我的自定义全局过滤器");
return chain.filter(exchange);
}

@Override
public int getOrder() {
return 0;
}
}

限流

限流算法

Gateway默认给我们实现了限流实现,也就是网关拦截器RequestRateLimiter,RequestRateLimiter的底层实现是令牌桶限流算法,需要引入Redis

image-20220417145409837

URL限流

引入Redis依赖

1
2
3
4
5
6
7
8
9
10
<!-- spring boot redis 缓存引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 缓存连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>

限流配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.ledao.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
* @author LeDao
* @company
* @create 2022-04-17 14:36
*/
@Configuration
public class KeyResolverConfig {

@Bean
public KeyResolver pathKeyResolver() {
/*return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getURI().getPath());
}
};*/
//URL限流,上面注释代码的lambda写法
return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
}
}

application.yml配置,把之前的MyGatewayFilterConfig这个类的@Configuration注解删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 2 #令牌桶总容量
redis-rate-limiter.requestedTokens: 1 # 每次请求消耗1个
key-resolver: "#{@pathKeyResolver}"

参数限流

限流配置类,只能存在一个限流Bean,多个会报错,请求时要带token参数(没有就无法请求)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.ledao.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
* @author LeDao
* @company
* @create 2022-04-17 14:36
*/
@Configuration
public class KeyResolverConfig {

/**
* 参数限流
*
* @return
*/
@Bean
public KeyResolver parameterKeyResolver() {
return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("token")));
}
}

application.yml配置,在之前的基础上直接修改key-resolver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 2 #令牌桶总容量
redis-rate-limiter.requestedTokens: 1 # 每次请求消耗1个
key-resolver: "#{@parameterKeyResolver}"

IP限流

限流配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.ledao.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
* @author LeDao
* @company
* @create 2022-04-17 14:36
*/
@Configuration
public class KeyResolverConfig {

/**
* IP限流
*
* @return
*/
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
}
}

application.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
application:
name: gateway
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
gateway:
routes:
- id: order
uri: http://localhost:8081/
predicates:
- Path=/order/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 2 #令牌桶总容量
redis-rate-limiter.requestedTokens: 1 # 每次请求消耗1个
key-resolver: "#{@ipKeyResolver}"

PS.

官方文档地址:Spring Cloud Gateway