GateWay
(1)简介
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
github:https://github.com/apex/gateway
(2)为什么使用Gateway
Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。
比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。
比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。
(3)概念
搭建Spring cloud alibaba gateway
1、pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-2021</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-alibaba-2021-gateway</artifactId>
<dependencies>
<!-- nacos 服务注册发现(客户端)依赖 -->
<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>
<!--spring-cloud-dependencies 2020.0.0 版本不在默认加载bootstrap.yml 文件,如果需要加载bootstrap 文件需要手动添加依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--loadbalancer ,负载均衡,用来替代ribbon的组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
</project>
2、父项目添加module
在 parent工程的 pom.xml 文件中加入以下内容
<modules>
<module>spring-cloud-alibaba-2021-gateway</module>
</modules>
3、配置文件
为了方便查看层级关系,这里将配置分为2个:
bootstrap.yml
:用来存放注册中心配置application.yml
:用来存放网关配置
bootstrap.yml 内容如下
spring:
application:
name: gateway-demo
profiles:
active: yexindong_active
cloud:
nacos:
discovery:
server-addr: chn520.cn:8848 # 服务注册中心地址
namespace: public # 注册到nacos的名称空间,默认为public
application.yml 内容如下
# 应用服务 WEB 访问端口
server:
port: 8090
spring:
# 后面的bean会覆盖前面相同名称的bean
main:
allow-bean-definition-overriding: true
cloud:
gateway:
discovery:
locator:
#表示gateway开启服务注册和发现功能,
#并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务
enabled: true
#表示将请求路径的服务名配置改成小写 因为服务注册的时候,向注册中心注册时将服务名转成大写的了
lower-case-service-id: true
# alibaba在2020版之后不使用ribbon,这里使用loadbalancer代替,在配置文件中禁用ribbon
# loadbalander:
# ribbon:
# enable: false
4、gateway 过滤器
创建 GatewayFilter.java
文件,内容如下
package com.alibaba.cloud.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* gateway 过滤器
*/
@Component
public class GatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("进入过滤器...");
// 获取请求对象request
ServerHttpRequest request = exchange.getRequest();
System.out.println("请求url:" + request.getURI().getPath());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
5、启动类
创建 GatewayApp.java
文件,内容如下
package com.alibaba.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApp {
public static void main(String[] args) {
SpringApplication.run(GatewayApp.class, args);
}
}
6、测试
注意: gateway 在默认情况下,会转发所有的服务的请求,前提是这些服务已经注册到nacos/eureka
在浏览器输入地址: http://127.0.0.1:8090/serviceName/order/getOrderList
; 将serviceName
改为你自己的服务名称;网关就会自动访问对应服务的地址;
比如我访问的地址是:http://127.0.0.1:8090/order-demo/order/getOrderList
;网关就会自动去访问 order-demo
服务地址:http://127.0.0.1:8088/order/getOrderList
(order-demo服务的端口为8088); 访问成功了,如下图:
7、配置gateway路由转发策略
7.1、根据路径匹配
在 application.yml
加入以下内容
spring:
cloud:
gateway:
routes:
- id: order_route1 # 路由的唯一标识
# 需要转发的地址,这里直接转发到 nacos 中注册的 order-demo 服务, lb表示使用本地负载均衡策略
uri: lb://order-demo
# 配置断言规则
predicates:
- Path=/o/**
# 过滤器
filters:
- StripPrefix=1 # 转发之前去掉第一层路由,比如请求 /x1/x2/x3,转发后会变成/x2/x3
然后在浏览器访问 :http://127.0.0.1:8090/o/order/getOrderList
就会自动转发到 order-demo
服务的http://127.0.0.1:8088/order/getOrderList
(order-demo服务的端口为8088);访问成功了,如下图:
除此之外,gateway还有其他的转发规则
7.2、时间点后匹配
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2022-02-20T17:42:47.789-07:00[America/Denver]
7.3、时间点前匹配
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2022-02-20T17:42:47.789-07:00[America/Denver]
7.4、时间区间匹配
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2022-01-20T17:42:47.789-07:00[America/Denver],
2022-01-21T17:42:47.789-07:00[America/Denver]
7.5、指定Cookie正则匹配指定值
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=cookie,china
7.6、指定Header正则匹配指定值
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id
7.7、请求Host匹配指定值
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
7.8、请求Method匹配指定请求方式
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
7.9、请求路径正则匹配
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
7.10、请求包含某参数
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
7.11、请求包含某参数并且参数值匹配正则表达式
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
7.12、远程地址匹配
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24