网关是微服务中不可或缺的部分。使用网关后,网关统一向外部系统提供REST API。在Spring Cloud中,使用Zuul、Spring Cloud Gateway等作为API GateWay来实现动态路由、监控、回退、安全等功能。
Spring Cloud Gateway 是Spring Cloud生态系统中的网关,是基于Spring 5.0、Spring Boot 2.0和Project Reactor 等技术开发的,旨在为微服务提供简单有效的、统一的API路由管理方式,并为微服务提供安全、监控、指标和弹性功能。
注意: Spring Cloud Gateway 用 “Netty + Webflux”实现, 不要加入Web依赖,否则会报错。需要加入Webflux依赖。
Spring Cloud Gateway 特点
- 基于Spring 5.0、Spring Boot 2.0构建和Project Reactor 等技术开发
- 能够匹配任何请求属性的路由
- 易于编写谓词(Predicate)和过滤器(Filters)
- 其Predicates和Filters可作用与特定路由
- 支持路径重写
- 支持动态路由
- 集成了Hystrix断路器
- 集成了Spring Cloud DiscoveryClient
- 支持限流
Spring Cloud Gateway工作流程
工作流程为:
(1)客户端向Spring Cloud Gateway发送请求。
(2)DispatcheHandle接收用户请求
(3)RoutePredicateHandleMapping进行路由匹配
(4)如果网关处理程序发现请求与路由匹配,则将请求发送至FilteringWebHandle(即网关处理程序)。如果发现请求与路由不匹配,则将请求返回给DispatcherHandle处理。
(5)FilteringWebHandle通过特定过滤器发送请求,先执行所有“PRE”逻辑,然后进行代理请求,最后执行“POST”逻辑。
(6)FilteringWebHandle将请求转发到具体的服务中。
(7)FilteringWebHandle将处理结果返回给用户
快速入门
- Spring Boot版本 2.1.7
- Consul版本1.8.4
- Spring Cloud版本Greenwich.SR2
配置路由规则方式
Spring Cloud Gateway网关路由有两种默认配置方式。
- Java API方式配置
- 在配置文件中配置
实现案例如下:
准备工作
服务端配置,经Gateway把请求路由转发到该服务上
新建新的子模块 spring-cloud-service-consumer
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- web依赖,提供服务-->
dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置文件添加
spring:
application:
name: service-consumer
cloud:
consul:
host: localhost
port: 8500
discovery:
register: false
service-name: service-consumer
server:
port: 8088
定义Controller,发布HTTP接口
@RestController
@RequestMapping("/user")
public class UserController {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@GetMapping(value = "/info")
public String info() {
LocalDateTime localDateTime = LocalDateTime.now();
String dateStr = DATE_TIME_FORMATTER.format(localDateTime);
return "User info: {\"name\":\"zsp\", \"age\":30, \"date\": " + dateStr + "}";
}
}
实现过程
1. 添加依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ping</groupId>
<artifactId>cloud-gateway-consul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud-gateway-consul</name>
<description>cloud-gateway基于consul</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1 方式一: 在配置文件中配置路由
server:
port: 8220
spring:
cloud:
gateway:
routes:
- id: user
uri: http://localhost:8088
predicates:
- Path=/user/**
logging:
level:
ROOT: debug
测试路由效果
启动项目,访问http://localhost:8020/user/info, 可以看到控制台信息
当请求匹配了路由ID为“user”的路由时,匹配的路由方式为“Paths”。 Spring Cloud Gateway会把请求转发到地址http://localhost:8088/user/info.
2.2 方式二: 在配置文件中配置路由
@SpringBootApplication
public class CloudGatewayConsulApplication {
public static void main(String[] args) {
SpringApplication.run(CloudGatewayConsulApplication.class, args);
}
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder
.routes()
.route("user", r -> r.path("/user/info")
.uri("http://localhost:8088/user/info")).build();
}
}
测试路由效果
当请求匹配了路由ID为“user”的路由时,匹配的路由方式为“Paths”。 Spring Cloud Gateway会把请求转发到地址http://localhost:8088/user/info。