网关(Gateway)是指在计算机网络中,用于连接两个不同网络的网络设备或软件。它可以将来自一个网络的请求转发到另一个网络,并将响应返回给原始网络。网关通常用于将本地网络连接到互联网,或将一个局域网连接到另一个局域网。在互联网上,网关通常是用于连接企业内部网络和互联网的设备,也被称为企业网关(Enterprise Gateway)。
在现代的分布式系统中,网关也可以指 API 网关(API Gateway),它是用于管理和保护后端服务的服务器软件。API 网关通常充当所有请求和响应的中间层,提供路由、安全、缓存、限流等功能。它还可以将多个微服务组合成一个 API,使其对外提供统一的接口。
总的来说,网关是一种连接不同网络或系统的设备或软件,用于转发和管理数据流量,实现网络间的通信和数据交换。
API 网关的主要作用:
综上所述,API 网关是一种非常重要的中间层,可以帮助开发者管理和保护后端服务,并提高系统的可用性、可靠性和性能。
Spring Cloud Gateway 是一个基于 Spring Framework 5 和 Spring Boot 2 的 API 网关服务。它提供了一些常见的路由、过滤、限流等功能,可以帮助开发者快速地构建出高性能、高可用的 API 网关服务。它是 Spring Cloud 生态系统中的一个组件,支持多种路由规则和路由断言,可轻松地实现 API 的路由和负载均衡。
Spring Cloud Gateway 基于异步非阻塞的 Reactor 模型作为底层技术栈,使用 Netty 作为 HTTP 服务器,可以处理高并发的请求。它的路由规则和路由断言可以根据请求的 URI、请求头、请求方法等信息,将请求路由到不同的后端服务,并使用负载均衡算法将请求分发到多个实例中,从而提高系统的可用性和性能。
Spring Cloud Gateway 还提供了一些过滤器,用于请求和响应的处理和转换,以及实现一些常见的功能,如安全认证、限流、重试等。它可以与 Spring Cloud Config、Spring Cloud Discovery、Spring Cloud Security 等其他 Spring Cloud 组件集成使用,提供更全面的功能和更好的开发体验。
总的来说,Spring Cloud Gateway 是一款强大的 API 网关框架,可以帮助开发者构建出高性能、高可用的 API 网关服务,简化微服务架构中的网关层设计和开发。
在需要创建网关的项目添加一个module;
添加网关依赖、nacos服务发现依赖;
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
例:
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
路由断言工厂(Route Predicate Factory)是 Spring Cloud Gateway 中的一个概念,用于配置路由规则中的断言条件,根据请求的不同属性匹配对应的路由。
路由断言工厂包括多个不同的实现类,每个实现类可以根据不同的请求属性,如 URI、请求头、请求参数等,配置不同的断言条件,如匹配正则表达式、等于、包含等。在配置路由规则时,可以使用多个路由断言工厂实现类组合使用,构建出复杂的断言条件,实现灵活的路由转发和负载均衡。
Spring Cloud Gateway 中内置了多个常用的路由断言工厂实现类,如 Path、Host、Method、Header、Cookie 等,还支持自定义路由断言工厂实现类,可以继承 RoutePredicateFactory 抽象类,实现匹配逻辑和参数解析等方法。
使用路由断言工厂可以根据不同的请求属性,灵活地配置路由规则,实现请求的路由转发和负载均衡。比如,可以根据请求的 URI 匹配路由规则,将请求路由到不同的后端服务,或者根据请求的请求头信息匹配路由规则,实现安全认证或者请求转发等功能
名称 | 说明 | 示例 |
---|---|---|
After | 根据请求的时间戳判断是否在指定时间之后。 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | 根据请求的时间戳判断是否在指定时间之前。 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | 根据请求的时间戳判断是否在指定时间段内。 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-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=.somehost.org,.anotherhost.org |
Method | 根据请求的 HTTP 方法进行匹配,支持 GET、POST、PUT、DELETE 等 HTTP 方法。 | - Method=GET,POST |
Path | 根据请求的 URI 路径进行匹配,支持 Ant 风格的通配符表达式。 | - Path=/red/{segment},/blue/** |
Query | 根据请求的查询参数进行匹配,支持精确匹配和正则表达式匹配。 | - Query=name, Jack或者- Query=name |
RemoteAddr | 根据请求的远程地址进行匹配,支持 IPv4 和 IPv6。 | - RemoteAddr=192.168.1.1/24 |
Weight | 根据请求响应时间进行匹配,支持权重分配和最小值匹配。 |
Spring Cloud Gateway 的网关过滤器(GatewayFilter)是 Spring Cloud Gateway 提供的核心组件之一,用于实现请求的过滤、处理和转换等功能。网关过滤器可以根据请求的不同阶段,对请求进行处理和转换,包括请求前置处理、请求后置处理、请求转发等功能。
Spring Cloud Gateway 中的网关过滤器基于 Reactor 模式实现,使用 Netty 作为底层网络框架,具有高性能和低延迟的特点。网关过滤器是一个链式处理器,可以根据需求配置多个过滤器组成处理链,对请求进行处理和转换。
Spring Cloud Gateway 的网关过滤器(GatewayFilter)的作用是对请求进行处理、转换和过滤。它们是 Spring Cloud Gateway 中非常重要的组件之一,可以在请求发送前或者请求返回后对请求进行处理,以实现请求的转发、重定向、限流、熔断、重试等功能。
网关过滤器是一个链式处理器,可以根据需求配置多个过滤器组成处理链,对请求进行处理和转换。网关过滤器在 Spring Cloud Gateway 中的作用包括:
Spring Cloud Gateway提供了很多的网关过滤器实现类(具体可查看Spring Cloud Gateway),以AddRequestHeader为例:
假设我们有一个服务 A,它需要向服务 B 发送请求,但是服务 B 需要在请求头中添加一个特定的参数才能正常处理请求。我们可以通过在 Spring Cloud Gateway 中使用 AddRequestHeaderGatewayFilterFactory 过滤器,为服务 A 发送的请求添加所需的请求头参数,以保证服务 B 能够正常处理请求。
下面是一个简单的示例配置:
spring:
cloud:
gateway:
routes:
- id: serviceA
uri: lb://serviceA
predicates:
- Path=/serviceA/**
filters:
- AddRequestHeader=X-Request-Id, 123
上述配置将服务 A 的请求路径前缀为 /serviceA/**,并在发送请求时添加一个名为 X-Request-Id,值为 123 的请求头参数。
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:
spring:
cloud:
gateway:
routes:
- id: serviceA
uri: lb://serviceA
predicates:
- Path=/serviceA/**
- id: serviceB
uri: lb://serviceB
predicates:
- Path=/serviceB/**
default-filters:
- AddRequestHeader=headerMsg,I like caterpillar!!!
全局过滤器(GlobalFilter)是 Spring Cloud Gateway 中的一种特殊的过滤器,它可以在请求被路由到具体的服务前或者服务返回响应后进行全局的处理。全局过滤器可以对请求和响应进行修改、记录日志、实现安全认证等全局性操作,是 Spring Cloud Gateway 的重要组成部分。
全局过滤器与普通过滤器的不同之处在于,它们不需要配置在具体的路由上,而是可以应用于所有的请求和响应。全局过滤器需要实现 Spring Cloud Gateway 的 GlobalFilter 接口,并实现其中的 filter 方法,在该方法中编写过滤器的逻辑代码。
全局过滤器在 Spring Cloud Gateway 中的作用包括:
Spring Cloud Gateway 提供了多种内置的全局过滤器实现类,同时也支持自定义全局过滤器实现类。全局过滤器是 Spring Cloud Gateway 中非常重要的组件之一,可以方便地实现请求和响应的全局处理和转换,以适应不同的业务场景和需求。
示例:
@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.否,拦截
//5.1设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//5.2拦截请求
return exchange.getResponse().setComplete();
}
//设置过滤器顺序
@Override
public int getOrder() {
return -1;
}
}
跨域指的是在 Web 应用程序中,当前页面的 URL 与请求资源的 URL 的协议、主机、端口不相同,导致浏览器出于安全考虑限制了对该资源的访问。例如,一个页面使用 Ajax 请求另一个网站的数据,由于协议、主机和端口不同,浏览器会阻止该请求。
跨域是一种安全机制,它可以保护 Web 应用程序免受来自其他域的恶意攻击。但有时候我们需要跨域请求数据或资源,这时需要通过一些手段来解决跨域问题,例如使用 JSONP、CORS、代理服务器等方式。
Gateway网关通过添加配置解决跨域:
spring:
cloud:
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:XXXX"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期