微服务 SpringCloud Gateway服务网关
1. gateway概述
1.1 gateway定义
SpringCloud Gateway是SpringCloud 的一个全新的项目,基于Spring5.0+SpringBoot2.0和Project Reactor等技术开发的第二代为服务网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。
SpringCloud Gateway作为SpringCloud 生态系统中的网关,目标是代替Zuul,在SpringCloud 2.0以上版本中,没有对新版本的Zuul2.0以上最新高性能版本进行集成,仍然还是使用的Zuul1.x非Reactor模式的老版本。二为了提升网关性能,SpringCloud Gateway是基于WebFlux框架实现的,二WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
SpringCloud Gateway的目标是提供统一的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全,监控,指标,限流等功能。
官网地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。

1.2 gateway使用场景
反向代理
鉴权
流量控制
熔断
日志监控
… …
1.3 gateway架构

1.4 zuul与gateway区别

1.5 gateway特性


2. gateway核心概念
服务网关三大核心概念
Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
Predicate(断言):参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

3. gateway工作流程
官网gateway工作流程。

gateway核心逻辑:路由转发+执行过滤器链
4. gateway配置方式
gateWay配置的两种方式:1.yml文件,2.配置类
4.1 yml配置断言路由(推荐,简单明了)
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
#- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
#- Cookie=username,zzyy
#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式
4.2 配置类配置断言路由
/**
* springcloud gateway配置类
*
* @author zrj
* @date 2021/2/2
* @since V1.0
**/
@Configuration
public class GatewayConfig {
/**
* 配置相当于在yml中配置了一个id为path_route_hello的路由规则
* 当访问地址http://localhost:9527/guonei的时候,gateway会通过断言是否为true
* 匹配到对应的URI地址:http://news.baidu.com/guonei
*
* @param routeLocatorBuilder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route( "path_route_hello",
r -> r.path( "/guonei" )
.uri( "http://news.baidu.com/guonei" ) ).build();
return routes.build();
}
}
5. gateway Predicate使用
5.1 Route Predicate Factories
Route Predicate Factories:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

5.2 gateway Route Predicate

具体参考1中的官网案例
1.After Route Predicate:- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
2.Before Route Predicate:- Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
3.Between Route Predicate: - Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
4. Cookie Route Predicate:- Cookie=username,zzyy
5. Header Route Predicate:- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式
6.Host Route Predicate:- Host=**.hello.com
7.Method Route Predicate: - Method=GET
8.Path Route Predicate:- Path=/payment/lb/** # 断言,路径相匹配的进行路由
9. Query Route Predicate: - Query=username, \d+ #要有参数名称并且是正整数才能路由
6. gateway Filter使用
6.1 什么是Filter过滤器
6.2 Filter的生命周期与种类

6.3 常用的GatewayFilter
过滤器地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

6.4 自定义过滤器
自定义过滤器通过实现接口GlobalFilter,Ordered。
implements GlobalFilter,Ordered
7. gateway案例
gateway案例git地址:https://github.com/zrj-coder/cloudboot3
7.1 maven依赖
<?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>cloudboot3</artifactId>
<groupId>com.hello.springcloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-gateway-gateway9527</artifactId>
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.hello.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--一般基础配置类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
7.2 yml配置
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
#- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
#- Cookie=username,zzyy
#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
7.3 代码实现
GatewayApplication9527
/**
* 网关服务启动类
*
* @author zrj
* @date 2021/2/2
* @since V1.0
**/
@EnableEurekaClient
@SpringBootApplication
public class GatewayApplication9527 {
public static void main(String[] args) {
SpringApplication.run( GatewayApplication9527.class, args );
}
}
GatewayConfig
/**
* springcloud gateway配置类
*
* @author zrj
* @date 2021/2/2
* @since V1.0
**/
@Configuration
public class GatewayConfig {
/**
* 配置相当于在yml中配置了一个id为path_route_hello的路由规则
* 当访问地址http://localhost:9527/guonei的时候,gateway会通过断言是否为true
* 匹配到对应的URI地址:http://news.baidu.com/guonei
*
* @param routeLocatorBuilder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route( "path_route_hello",
r -> r.path( "/guonei" )
.uri( "http://news.baidu.com/guonei" ) ).build();
return routes.build();
}
}
MyLogGatewayFilter
/**
* 自定义过滤器
*
* @author zrj
* @date 2021/2/2
* @since V1.0
**/
@Slf4j
@Component
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info( "***********come in MyLogGateWayFilter: " + new Date() );
String uname = exchange.getRequest().getQueryParams().getFirst( "uname" );
if (uname == null) {
log.info( "*******用户名为null,非法用户,o(╥﹏╥)o" );
exchange.getResponse().setStatusCode( HttpStatus.NOT_ACCEPTABLE );
return exchange.getResponse().setComplete();
}
return chain.filter( exchange );
}
@Override
public int getOrder() {
return 0;
}
}
DateTime
/**
* 获取当前时间,带时区
* 用于配置断言
*
* @author zrj
* @date 2021/2/2
* @since V1.0
**/
public class DateTime {
public static void main(String[] args) {
ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
System.out.println( zbj );
//2021-02-02T23:15:43.456+08:00[Asia/Shanghai]
}
}
本文详细介绍SpringCloud Gateway的服务网关功能,包括其定义、使用场景、架构及与Zuul的区别。涵盖核心概念如路由、断言和过滤器,并提供配置方式、使用案例等实战指南。


1万+

被折叠的 条评论
为什么被折叠?



