前言
1.网关是怎么演化来的
单体应用拆分成多个服务后,对外需要一个统一入口,解耦客户端与内部服务
(ps:图转网络,侵删)
2.网关的基本功能
- 网关核心功能是路由转发,因此不要有耗时操作在网关上处理,让请求快速转发到后端服务上
- 网关还能做统一的熔断、限流、认证、日志监控等
(ps:图转网络,侵删)
3.关于Spring Cloud Gateway
Spring Cloud Gateway是由spring官方基于Spring5.0、Spring Boot2.0、Project Reactor等技术开发的网关,使用非阻塞API,Websockets得到支持,目的是代替原先版本中的Spring Cloud Netfilx Zuul,目前Netfilx已经开源了Zuul2.0,但Spring 没有考虑集成,而是推出了自己开发的Spring Cloud GateWay。这里需要注意一下gateway使用的netty+webflux实现,不要加入web依赖(不要引用webmvc),否则初始化会报错 ,需要加入webflux依赖。
gateway与zuul的简单比较:gateway使用的是异步请求,zuul是同步请求,gateway的数据封装在ServerWebExchange里,zuul封装在RequestContext里,同步方便调式,可以把数据封装在ThreadLocal中传递。
Spring Cloud Gateway有三个核心概念:路由、断言、过滤器
过滤器:gateway有两种filter:GlobalFilter、GatewayFilter,全局过滤器默认对所有路由有效。
文档地址:cloud.spring.io/spring-clou…
网关作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,尽量避免重启,需要用到动态路由配置,在网关运行过程中更改路由配置
三大核心概念:
- Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true.
- 发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,
- Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.
- 就是java里的断言函数,匹配请求里的任何信息,包括请求头等
- Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.
- 这些是使用特定工厂构建的Spring Framework
GatewayFilter
实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。
它是如何工作的
客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。
下图提供了 Spring Cloud Gateway 如何工作的高级概述:
客户端向 Spring Cloud Gateway 发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关 Web 处理程序。此处理程序通过特定于请求的过滤器链运行请求。过滤器用虚线划分的原因是过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“预”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“发布”过滤器逻辑。
在没有端口的路由中定义的 URI 分别获得 HTTP 和 HTTPS URI 的默认端口值 80 和 443。 | |
---|---|
如何使用
1、建立一个单独的module作为网关,导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--其他相关依赖:-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--网关也需要注册进nacos注册中心中去,发现其他服务所在的位置,这样请求一进来,网关就能找到目标服务都在哪些机器,路由到指定位置-->
<!-- 服务注册/发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置中心来做配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、编写配置
2.1 在启动类上开启注册服务发现@EnableDiscoveryClient
/**
* 1、 开启服务注册发现
* 配置nacos的注册中心地址
*/
@EnableDiscoveryClient
//这里排除掉了关于数据库的配置,因为common中有数据库的配置,这里不需要用到
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallGatewayApplication.class, args);
}
}
2.2 配置nacos注册中心地址applicaion.properties
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
2.3 bootstrap.properties 填写配置中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
2.4 nacos里创建命名空间gateway,然后在命名空间里创建文件guilmall-gateway.yml
2.5 nacos里创建命名空间gateway,然后在命名空间里创建文件guilmall-gateway.yml,配置断言规则
- 代表是数组,可以配置多个断言规则对象
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url,qq
id是断言的名称,唯一
uri是只有断言成功后,才会路由到的指定的地址
predicates 断言规则
Query:详细的断言条件:有一个参数叫url,并且他的值包含qq
总结:第一条断言test_route指的是如果有一个参数叫url,并且他的值包含baidu,就会路由到https://www.baidu.com
第二条断言test_route指的是如果有一个参数叫url,并且他的值包含qq,就会路由到https://www.qq.com
官方文档: