第五次课:微服务网关之SpringcludGateway
分类: springboot 专栏: 新版springcloud分布式学习 标签: 网关gateway
2024-04-28 10:45:49 787浏览
前言
优化下之前的版本依赖管理。写了很多的version.很不方便。可以把nacos的版本和springcloud的版本管理依赖写到父级pom里
版本注意
spring cloud Alibaba version | springcloud version | springboot version |
2022.0.0.0-RC2 | springcloud 2022.0.0 | 3.0.2 |
2022.0.0.0-RC1 | springcloud 2022.0.0 | 3.0.0 |
<properties>
<alibaba.version>2022.0.0.0-RC1</alibaba.version>
<boot.version>3.0.0</boot.version>
<cloud.version>2022.0.0</cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
什么是网关
SpringCloud Gateway是Spring Cloud的一一个全新项目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统的API路由管理方式。
SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。 而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。Spring Cloud Gateway的目标提供统一的路由方式且基于Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
网关的功能
- 身份认证和权限校验
- 服务路由反向代理、负载均衡
- 请求限流
- 日志监控
springcloud-gateway使用
依赖
gateway-service 的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件application.yaml
server:
port: 9527
spring:
application:
name: gateway-service
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes: # 网关路由规则
- id: user-service #路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
uri: lb://user-service
predicates: #路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
路由配置包括:
1. 路由id:路由的唯一标示
2.路由目标 (uri) :路由的目标地址, http代表固定地址, lb代表据服务名负载均衡
3.路由断言 ( predicates) :判断路由的规则,
4.路由过滤器(filters) :对请求或响应做处理
路由断言工厂
- 我们在配置文件中写的断言规则只是字符串, 这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
- 例如Path=/order/**是按照路径匹配, 这个规则是由org. springframework cloud.gateway.handler.predicate PathRoutePredicateFactory类来处理的
Spring提供了11种基本的Predicate工厂
名称 | 说明 | 示例 |
After | 是某个时间点后的请求 | -After=2023-06-16T17:42:47.789-07:00[America/Denver] |
Before | 是某个时间点之前的请求 | - Before=2017-01-20T17:42:47.789-07:00[America/Denver] |
Between | 是某两个时间点之间的请求 | - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | 请求必须包含cookie | - Cookie=chocolate, ch.p |
Header | 请求必须包含某些header | - Header=X-Request-Id, \d+ |
Host | 请求必须是某个host(域名) | - Host=**.jf3q.com,**.jf3q.cn |
Method | 请求方式必须是指定方式 | - Method=GET,POST |
Path | 请求路径必须符合规则 | - Path=/red/{segment},/blue/{segment} |
Query | 请求参数必须包含指定参数 | - Query=green |
RemoteAddr | 请求者ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
Weight | 权重处理 | - Weight=group1, 2 |
其他可以查看spring官网
路由过滤器
针对某个路由
Spring提供了31种不同的路由过滤器工厂。例如:
名称 | 说明 |
AddRequestHeader | 给当前请求添加一个请求头 |
RemoveRequestHeader | 移除请求中的一个请求头 |
AddResponseHeader | 给响应结果中添加一个响应头 |
RemoveResponseHeader | 从响应结果中移除有一个响应头 |
RequestRateLimiter | 限制请求的流量 |
gateway:
routes: # 网关路由规则
- id: user-service #路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
uri: lb://user-service #路由的目标地址Lb就是负载均衡,后面跟服务名称
predicates: #路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
filters:
- AddRequestHeader=notice,my team is jf3q
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
默认过滤器
针对全部路由
gateway:
routes: # 网关路由规则
- id: user-service #路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
uri: lb://user-service #路由的目标地址Lb就是负载均衡,后面跟服务名称
predicates: #路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
filters:
- AddRequestHeader=notice,my team is jf3q
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
default-filters:
- AddRequestHeader=notice,my team is jfit
全局过滤器
通过自定义编码的方式实现处理一切进入网关的请求和微服务的响应,而不是上面那种配置的方式(不方便,不灵活)。
- 小案例:定义全局过滤器,拦截并判断用户角色
需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面的条件
参数种是否有role且是否是admin,是则放行,否则拦截。
@Order(1)//越小越靠前
@Component
public class AuthFilter implements GlobalFilter{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2.获取参数中的 role 参数
String auth = params.getFirst("role");
// 3.判断参数值是否等于 admin
if ("admin".equals(auth)) {
// 4.是,放行
return chain.filter(exchange);
}
// 5.否,拦截
// 5.1.设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2.拦截请求
return exchange.getResponse().setComplete();
}
}
过滤器执行顺序
跨域问题
gateway:
# ...
globalcors: #全局的跨城处理
add-to-simple-url-handLer-mapping: true #解决options 请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: #允许哪些网站的跨城请求
- "http://localhost:8080"
- "http://www.jf3q.com"
allowedMethods: #允许的跨城ojax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" #允许在请求中携带的头信息
allowCredentials: true #是否允许携带cookie
maxAge: 360000 #这次跨域检测的有效期
三大核心概念
Router(路由)
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
Predicate(断言)
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter(过滤)
指的是Spring框架中GatewayFilter的实例, 使用过滤器,可以在请求被路由前或者之后对请求进行修改。
总结
web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现个具体的路由了
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论
您可能感兴趣的博客