API网关-SpringCloud Gateway
Spring Cloud Gateway是一个基于Spring Framework的开源API网关,用于构建微服务架构中的统一访问层。它充当了应用程序和后端服务之间的代理,提供了路由、负载均衡、安全性、监控等功能,以简化微服务架构中的网络请求管理和流量控制。
Spring Cloud Gateway的主要特点包括:
- 动态路由: 可以根据请求的信息将流量路由到不同的后端服务,支持动态添加、删除和修改路由规则。
- 负载均衡: 可以自动分配流量到多个实例,以提高系统的可用性和性能。
- 断路器模式: 提供了断路器模式来处理后端服务的故障,防止故障服务对整个系统的影响。
- 过滤器: 可以在请求和响应之间应用一系列的过滤器,用于修改请求、响应或执行一些预处理/后处理操作。
- 限流和速率控制: 可以通过配置限制每个路由或服务的请求速率,以防止过载和滥用。
- 安全性: 可以集成Spring Security等安全框架,对请求进行认证和授权。
- 监控和日志: 提供了监控和日志功能,帮助开发人员了解流量和系统的状态。
- 易于扩展: 由于基于Spring Framework构建,因此可以通过自定义插件和过滤器来扩展其功能。
SpringCloud Gateway简单使用
添加依赖: 在生成的
pom.xml
文件中,添加Spring Cloud Gateway的依赖。通常,您需要添加以下依赖:1
2
3
4<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>因为我们使用了nacos实现服务注册与服务发现,所以也要引入nacos相关的依赖,如果不需要可以不引入,routes.uri直接指定目标服务的完整URL字符串。
1
2
3
4
5<!--nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>配置路由: 在
application.yml
或application.properties
中配置您的路由规则。以下是一个简单的示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25server:
port: 10010
spring:
application:
name: gateway
gateway:
routes:
# 路由标示,必须唯一
- id: user-service
# 路由的目标地址
uri: lb://user-service
# 路由断言,判断请求是否符合规则
predicates:
# 路径断言,判断路径是否是以/user开头,如果是则符合
- Path=/user/**
filter:
#添加路由过滤器
- AddRequestHeader=Tag,userRequest
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
#添加default过滤器
default-filters:
- AddRequestHeader=origin,gateway直接URL字符串: 最简单的写法就是直接指定目标服务的完整URL字符串。
uri: http://example.com
lb协议: 使用
lb
协议可以通过服务发现来进行负载均衡,将请求分发到不同实例。uri: lb://service-name
lb协议 + 负载均衡策略: 可以在
lb
协议后面添加负载均衡策略,如lb://service-name?lbMethod=ROUND_ROBIN
。uri: lb://service-name?lbMethod=ROUND_ROBIN
使用自定义协议: 您可以定义自己的协议前缀,然后在目标URI中使用。
uri: custom://destination
使用表达式: 您可以在
routes.uri
中使用SpEL表达式来动态生成目标URI。uri: "'http://dynamic-' + #serviceId + '.example.com'"
测试路由: 启动应用程序后,您可以使用浏览器或工具(如curl或Postman)来测试配置的路由。访问
http://localhost:10010/user/1
应该将请求代理到http://user-service/user/1
。![image-20230817210750025](../../../../Library/Application Support/typora-user-images/image-20230817210750025.png)
添加GlobalFilter简单实现访问鉴权
GlobalFilter
是Spring Cloud Gateway中的一个重要概念,它允许您在请求和响应的生命周期中执行全局操作。这些操作可以用于各种目的,如身份验证、日志记录、添加请求头、处理异常等。GlobalFilter
可以在整个网关的请求处理流程中应用,无论是在路由匹配之前还是之后。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@Service
public class AuthorizeFilter implements GlobalFilter, Ordered {
@SneakyThrows(Exception.class)
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
//获取参数中的 authorization 参数 。通常是获取header里的authorization
String authorization = params.getFirst("authorization");
//这里demo简单处理 判断数值是否等于 admin
if ("admin".equals(authorization)) {
//放行
return chain.filter(exchange);
}
//先设置状态码
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
DataBufferFactory bufferFactory = response.bufferFactory();
ObjectMapper objectMapper = new ObjectMapper();
DataBuffer wrap = bufferFactory.wrap(objectMapper.writeValueAsBytes(new RestResult<>(401, "unauthrize")));
return response.writeWith(Mono.fromSupplier(() -> wrap));
// //拦截请求
// return exchange.getResponse().setComplete();
}
//设置优先级为-1
@Override
public int getOrder() {
return -1;
}
}上面代码通过对请求参数里的authorization是否等于admin简单实现了鉴权,是admin则通过
![image-20230817211428288](../../../../Library/Application Support/typora-user-images/image-20230817211428288.png)
否则返回401 httpstatus和json responsebody提示
![image-20230817211437210](../../../../Library/Application Support/typora-user-images/image-20230817211437210.png)
集成nacos配置中心实现动态路由
添加依赖:在上面配置的依赖的基础上添加nacos-config相关的依赖
1
2
3
4
5<!-- nacos的配置管理依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>配置Nacos作为配置中心: 在
bootstrap.yaml
或bootstrap.properties
中配置Nacos的配置中心信息,包括Nacos Server的地址和配置的Data ID、Group等信息。bootstrap.yaml
1
2
3
4
5
6
7
8
9
10spring:
application:
name: gateway
profiles:
active: dev # 环境
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
config:
file-extension: yaml # 文件后缀application.yaml
1
2
3
4
5
6
7
8
9server:
port: 10010
logging:
level:
com.cason: debug
spring:
cloud:
nacos:
server-addr: localhost:8848配置动态路由: 在Nacos配置中心中创建配置,用于定义动态路由规则。配置的Data ID可以根据您的实际情况进行定义,我这里用的是<spring.application.name>-<spring.profiles.active>.yaml以下是一个示例配置:
测试
访问user,order相关路由没有问题
移除user相关的路由,请求user相关路由404,请求order相关路由没有问题