SpringCloud-(六)GateWay的部署安装和快速使用

本文最后更新于:October 30, 2022 pm

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

目录

导入依赖

1
2
3
4
5
6
7
8
9
10
11
<!-- 路由网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- 注册到nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

添加配置文件

同样的,也是需要注册到nacos中的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server:
port: 8500
spring:
datasource:
druid:
username: root
password: root
url: jdbc:mysql://ip:3306/home?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: ip:port # nacos的注册地址和端口

📢注意:需要排除以下依赖。而且如果引入了MyBatis或者MyBatis-plus,则还需要配置数据库相关的东西!!!

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

如果想实现不导入父模块中的依赖,但是需要父模块中的依赖管理,则可以这样导入父模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--    不使用这种导入   -->
<!-- <parent>-->
<!-- <artifactId>InkM</artifactId>-->
<!-- <groupId>com.tothefor</groupId>-->
<!-- <version>0.0.1-SNAPSHOT</version>-->
<!-- </parent>-->

<!-- 导入依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tothefor</groupId>
<artifactId>InkM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

个人总结:

  • parent:会让子模块也会有相同的依赖。
  • dependencyManagement:只会让子模块具有父模块相同的依赖环境,而不会真正导入依赖。

完整环境配置

pom文件内容:

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
59
60
61
62
63
64
65
66
67
68
69
70
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tothefor</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>Demo project for Spring Boot</description>

<dependencies>
<!-- 路由网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- 注册到nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>

<!-- 导入父模块的依赖环境 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tothefor</groupId>
<artifactId>InkM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.6</version>
<configuration>
<mainClass>com.tothefor.gateway.GatewayApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

配置文件application.yml:(采用这种方式后,就不会从父模块中继承MyBatis之类的依赖了,所以就可以去掉了)

1
2
3
4
5
6
7
8
9
10
server:
port: 8500
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: ip:80

配置路由

在gateway模块中进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server:
port: 8500
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: nacosIp:80
gateway:
routes:
- id: adminservice # 唯一标识
uri: lb://admin-service # 注册到Nacos的服务名称
predicates:
- Path=/adminT/admin/** # adminT是在自己模块中设置的context-path,admin是Controller类上的

当访问 http://localhost:8500/adminT/admin/c 时,会转发到 http://admin-service/adminT/admin/c

然后访问网关:http://localhost:8500/adminT/admin/c,会发现报错了,如下:

1
2
3
4
5
Whitelabel Error Page
This application has no configured error view, so you are seeing this as a fallback.

Thu Oct 06 12:48:17 CST 2022
[9eceed8e-1] There was an unexpected error (type=Service Unavailable, status=503).

原因:由于springcloud2020弃用了Ribbon,因此Alibaba在2021版本nacos中删除了Ribbon的jar包,因此无法通过lb路由到指定微服务,出现了503情况。添加依赖即可,如下:

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

然后再次访问,即可成功。

多个路由配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server:
port: 8500
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: ip:80
gateway:
routes:
- id: adminservice
uri: lb://admin-service
predicates:
- Path=/adminT/admin/**
- id: userservice
uri: lb://user-service
predicates:
- Path=/userT/user/**

路由过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server:
port: 8500
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: ip:80
gateway:
routes:
- id: adminservice
uri: lb://admin-service
predicates:
- Path=/adminT/admin/**
filters: # 增加请求头信息,key为TTF,value为123qweasdzxc
- AddRequestHeader=TTF,123qweasdzxc # 优先级默认为1
- id: userservice
uri: lb://user-service
predicates:
- Path=/userT/user/**

在此加载的请求头信息可以直接在Controller的接口中进行获取:

1
2
3
4
@RequestMapping("/gtw")
public static void get(HttpServletRequest request){
String ttf = request.getHeader("TTF");
}

也可以自定义全局过滤器,使其能够作用于全局。

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
package com.tothefor.gateway.filter.GlobalFilter;//package com.tothefor.sdk.filter.GlobalFilter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
* @Author DragonOne
* @Date 2022/10/23 19:54
* @Title
* @Description
*/

@Component
public class GatewayTokenFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求头中的信息
List<String> ttf1 = request.getHeaders().get("TTF");
// 获取所有请求参数
MultiValueMap<String, String> queryParams = request.getQueryParams();
List<String> ttf = queryParams.get("TTF");
return null;
}
}

📢注意:在配置文件中配置的过滤器也具有优先级,从上到下默认从1开始设置。值越小优先级越高。如果自定义全局过滤器和配置文件中单独的过滤器优先级相同时,自定义的全局过滤器优先执行。

给自定义全局过滤器添加优先级:

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
package com.tothefor.gateway.filter.GlobalFilter;//package com.tothefor.sdk.filter.GlobalFilter;

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

import java.util.List;

/**
* @Author DragonOne
* @Date 2022/10/23 19:54
* @Title
* @Description
*/

@Component
public class GatewayTokenFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求对象
ServerHttpRequest request = exchange.getRequest();
// 获取请求头中的信息
List<String> ttf1 = request.getHeaders().get("TTF");
// 获取所有请求参数
MultiValueMap<String, String> queryParams = request.getQueryParams();
List<String> ttf = queryParams.get("TTF");
if(1>0){
// 满足要求,放行
return chain.filter(exchange);
}else{
// 不满足,直接结束
return exchange.getResponse().setComplete();
}
}

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

现在自定义全局过滤器的值为0,则会优先于配置文件中的过滤器执行。


本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/abb839f4.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!