认识学习
Spring Cloud Gateway 是一个基于 Spring Boot 的构建网关的开源项目。它旨在为微服务架构提供统一的入口点,以便进行路由、过滤和负载均衡等操作。Spring Cloud Gateway 建立在 Spring Framework 5、Project Reactor 和 Spring Boot 2 的基础上。
Spring Cloud Gateway 提供了一组核心概念和组件,用于构建灵活的网关应用:
- 路由(Routes):定义请求的匹配规则和转发目标,将请求发送到后端服务。
- 过滤器(Filters):允许在请求被转发到后端服务之前或之后进行自定义逻辑处理,如修改请求/响应、日志记录、认证授权等。
- 负载均衡(Load Balancer):支持在转发请求时进行负载均衡,将请求分发到后端服务的多个实例中。
- 断路器(Circuit Breaker):通过集成 Hystrix 等断路器库,提供故障保护和容错功能,防止级联故障。
- 监控与指标(Metrics):支持集成 Spring Cloud Sleuth 和 Micrometer,用于跟踪和监控网关的性能和行为。
- 动态配置(Dynamic Configuration):支持使用 Spring Cloud Config 或其他配置中心来管理路由和过滤器的动态配置。
Spring Cloud Gateway 的设计目标是提供高性能、低延迟和可扩展的网关解决方案。开发人员可以使用 Java 或 Kotlin 编写自定义的路由和过滤器,以满足特定需求。
总结而言,Spring Cloud Gateway 是一个基于 Spring Boot 的灵活、轻量级的网关框架,用于构建和管理微服务架构中的统一入口点,提供路由、过滤、负载均衡和断路器等功能。它是 Spring Cloud 生态系统中的重要组件之一,有助于简化微服务架构的开发和运维。
使用
网关搭建
- 在微服务项目中创建网关模块和其启动类,并导入依赖
<!--服务发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 配置application文件
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848
gateway:
# 配置路由
routes:
# 唯一
- id: user-service
# 可以是http固定地址,也可以是lb根据服务名称进行负载均衡
uri: lb://userservice
# 断言返回booleean类型,进行路由判断
predicates:
- Path=/user/**
# 路由过滤器
filters:
- AddRequestHeader=filters
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
# 默认过滤器
default-filters:
- AddRequestHeader=default-filters
过滤器
- 路由过滤器
filters
过滤器可以对请求或响应进行加工处理,比如添加请求头
配置在路由下的过滤器只对当前路由生效
defaultFilter
对所有路由都生效,与routes同级
- 全局过滤器GlobalFilter
①实现GlobalFilter接口
②添加@Order注解或实现Ordered接口
③编写处理逻辑
//@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 获取其你去参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2. 获取参数中的authorization参数
String auth = params.getFirst("authorization");
// 3. 判断参数值是否等于admin
if ("admin".equals(auth)) {
// 4. 是,放行
return chain.filter(exchange);
}
// 5. 否,拦截
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2 请求拦截
return exchange.getResponse().setComplete();
}
/**
* 功能如上注解,顺序过滤,值越小越优先
* @return
*/
@Override
public int getOrder() {
return -1;
}
}
网关跨域问题
- 跨域:域名不同或者端口号不同都为跨域
- 跨域问题:浏览器禁止请求的发送者与服务端发生跨域的Ajax请求,请求被浏览器拉结的问题。
网关中的解决方法
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
# filters:
# - AddRequestHeader=filters
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters:
- AddRequestHeader=default-filters
# 这里是核心
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "网站url"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期