Ezio's Blog
Posts Categories Tags Music Mood About
Ezio's Blog· Light
☰ Menu
Posts Categories Tags Music Mood About
Expand all Back to top Go to bottom

Spring Gateway

Author: Ezio Date: August 23, 2022  14:31:21 Category: Spring Cloud

搭建网关服务

1.新建一个module,引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- nacos服务发现依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.1.0</version>
</dependency>
<!--网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2.编写路由配置以及nacos配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server:
port: 10010
logging:
level:
cn.ezio: debug # 日志级别
pattern:
dateformat: MM-dd HH:mm:ss:SSS # 日期格式
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes:
- id: user-service # 路由标示,必须唯一
uri: lb://userservice # 路由的目标地址
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**

路由的过滤器配置 GatewayFilter

在配置用添加过滤器配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes:
- id: user-service # 路由标示,必须唯一
uri: lb://userservice # 路由的目标地址
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: # 路由过滤器配置,default-filters默认过滤器,全局过滤所有路由都生效。
- AddRequestHeader=Truth,Java is Best!

自定义路由断言工厂

继承 AbstractRoutePredicateFactory 类

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
@Component
@Slf4j
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

public MyRoutePredicateFactory() {
super(Config.class);
}

@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
if (config.getName().equals("ylw")) {
log.info("路由失败");
return false;
}
return true;
};
}

@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("name");
}

public static class Config {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

}

自定义过滤器工厂

继承 AbstractGatewayFilterFactory 或 AbstractNameValueGatewayFilterFactory 类,两者区别在于接受参数的个数,前者一个,后者可接受两个。

  • Pre 类型过滤器,逻辑处理在 chain.filter() 之前。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component
@Slf4j
public class PreGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
log.info("调用PreGatewayFilterFactory==="
+ config.getName() + ":" + config.getValue());
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
System.out.println("请求头:" + headers);
return chain.filter(exchange);
};
}
}
  • Post 类型过滤器,逻辑处理在 chain.filter() 执行后。
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
@Component
@Slf4j
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

public PostGatewayFilterFactory() {
super(Config.class);
}

@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("调用PostGatewayFilterFactory==="
+ config.getName() + ":" + config.getValue());
}));
}

@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(GatewayFilter.NAME_KEY, GatewayFilter.VALUE_KEY);
}

public static class Config {

private String name;

private String value;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

}

自定义全局过滤器 GlobalFilter

实现GlobalFilter接口,自定义处理逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component
@Slf4j
public class MyGlobalFilter implements GatewayFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info(exchange.getRequest().getPath().value());
return chain.filter(exchange);
}

@Override
public int getOrder() {
return -1;
}
}

过滤器执行链顺序

请求进入网关,会经过三种过滤器:局部路由过滤器、DefaultFilter、GlobalFilter。

请求路由后,会将当 局部路由过滤器、DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器。

Order值相同时:

1.两个GlobalFilter类型的过滤器Order值相同时,根据文件名字母排序,文件名靠前的优先更高。

原因是包扫描时是按照文件的顺序扫描的,然后封装到List集合的,通过Order值排序时如果Order值相同,文件名在前名的依然会排在前面。

2.GlobalFilter类型和GatewayFilter类型的过滤器Order值相同时,GlobalFilter类型优先更高。

原因是这两种过滤器最终会合并到一个过滤器集合中形成过滤器调用链,源码是通过list.addAll();方法将GatewayFilter类型的过滤器加到了GlobalFilter过滤器集合中,addAll()是末尾添加方式,所以Order值相同时GatewayFilter类型的过滤器会排在后面。

Order值生成规则:

1.GlobalFilter类型过滤器,通过实现Ordered接口的getOrder()方法设置。

2.GatewayFilter类型过滤器,通过配置文件中配置的过滤器顺序自动生成,固定从1开始封装,例如配置了三个过滤器,则按照从上往下顺序Order值依次为1、2、3。


网关跨域问题处理

跨域:域名不一致或端口不同,浏览器的同源策略导致的跨域问题。浏览器禁止请求的发起者与服务端发生跨域的ajax请求,请求被浏览器拦截。

Author: Ezio

Permalink: https://ezioy.cn/2022/08/23/Gateway/

License: Copyright (c) 2019 CC-BY-NC-4.0 LICENSE

Slogan: Nothing is true,Everything is permitted

Tag(s): # Spring Gateway # Spring Cloud
back · home
Spring Webflux 消息堆积
Ezio © 2019 - 2026 | Powered by Hexo & Chic | 访客数量:   浏览次数: | 渝公网安备50011302222043 | 渝ICP备2023013933号-1