Spring Cloud Gateway 是一个构建在 Spring Framework、Project Reactor 和 Spring Boot 之上的 API 网关。它主要用于处理 API 请求,执行各种策略如路由、过滤和转发,然后将请求代理到适当的微服务。下面简要概述了 Spring Cloud Gateway 的工作原理:
路由(Route): 路由是网关的基础构建块,由一个 ID、一个目标 URI、一系列断言和一系列过滤器组成。如果断言为真,则将请求路由到 URI。
断言(Predicate): 断言用于匹配 HTTP 请求的各个属性,如路径、头、方法等。
过滤器(Filter): 一旦断言成功,过滤器会被应用于请求或响应的修改。
接收请求: Spring Cloud Gateway 首先接收到从客户端发来的请求。
匹配路由: 网关根据请求的属性(如 URL、HTTP 方法或头部信息等)匹配预定义的路由。这是通过断言完成的。
执行过滤器: 在路由到下游服务之前和之后,可以应用各种过滤器来修改请求和响应。
代理请求: 一旦匹配到合适的路由并执行了所有的过滤器,网关将请求代理到对应的下游服务。
获取响应: 网关从下游服务获取响应,并通过任何配置的后置过滤器。
返回响应: 最终,经过所有处理和过滤后的响应返回给客户端。
Spring Cloud Gateway 使用了非阻塞 API 和 Project Reactor,从而确保高吞吐量和低延迟。
通过这样的机制,Spring Cloud Gateway 不仅仅是一个简单的代理服务,还可以添加各种中间层功能,如安全性验证、限流、监控等。
这样的设计使得 Spring Cloud Gateway 非常适合微服务架构,它可以很容易地与其他 Spring Cloud 组件和服务集成,为微服务提供统一的入口点和管理界面。
添加依赖,添加nacos依赖报错时添加指定的版本号就行了。
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-gateway
application.yml配置文件
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848 #nacos地址,把自己也注册到nacos
gateway:
routes: #定义路由规则数组
- id: user-service #路由标识,必须唯一
uri: lb://userservice #路由的目标地址,lb表示负载均衡模式,也可以直接写http地址
predicates: #路由断言,判断请求是否符合规则
- Path=/user/** #路由断言,判断路径是否以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
只有条件都符合时才会放行,在predicates下进行配置。
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理,比如添加请求头,GatewayFilter通过配置定义,处理逻辑是固定的。
filters:对当前请求进行添加过滤器(局部过滤器,不能自定义)。
default-filters:对所有请求添加过滤器(全局过滤器,不能自定义)。
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848 #nacos地址,把自己也注册到nacos
gateway:
routes: #定义路由规则数组
- id: user-service #路由标识,必须唯一
uri: lb://userservice #路由的目标地址
predicates: #路由断言,判断请求是否符合规则
- Path=/user/** #路由断言,判断路径是否以/user开头,如果是则符合
filters: #针对当前实例添加过滤器
- AddRequestHeader=Truth, Itcast is freaking awesome! #添加请求头,只对user的服务添加
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters: #对所有的服务添加过滤器
- AddRequestHeader=xin, xin is freaking awesome!
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样,区别在于GlobalFilter的逻辑需要自己写代码实现(可以自定义)。
定义一个类实现GlobalFilter接口,再交给Spring管理就可以了。
在Spring WebFlux和Spring Cloud Gateway中,filter方法是用于处理HTTP请求和响应的核心部分。这个方法通常定义在一个实现了GatewayFilter接口的类中。filter方法接收两个参数:
@Order(1) //过滤器的执行顺序,越小优先级越高可以为负数
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取请求参数
ServerHttpRequest request = exchange.getRequest();
//获取参数中的authorization参数
MultiValueMap params = request.getQueryParams();
String auth = params.getFirst("authorization");
if (auth.equals("admin")) { //这里可能为null,注意处理一下
//放行
return chain.filter(exchange);
}
//设置状态码,401一般表示未登录
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//拦截
return exchange.getResponse().setComplete();
}
}
声明顺序由当前层次的过滤器按顺序来递增优先级,不同乘次的过滤器优先级相同的情况下,defaultFilter>路由过滤器>GlobalFilter过滤器。
因为请求是先经过网关,再去微服务,在微服务配置跨域是进不来了,因为网关不会放行。
spring:
cloud:
nacos:
server-addr: localhost:8848 #nacos地址,把自己也注册到nacos
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站来的请求可以跨域,只有这两个网站来的请求可以跨域
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
allowedOrigins:
- "*"
allowedMethods:
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*"
maxAge: 360000