GateWay网关

概述简介

Gateway是在 Spring生态系统之上构建的AP网关服务,基于 Spring5, Spring Boot2和 Project Reactor等技术。

Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试

官网地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/



SpringCloud Gateway是 Spring Cloud的个全新项目,基于 Spring5.0+ Spring Boot2.0和 Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式

SpringCloud Gateway作为 Spring Cloud生态系统中的网关,目标是替代zuul,在 Spring Cloud2.0以上版本中,没有对新版本的zuul2.0以上最新高性能版本进行集成,仍然还是使用的zuul1.×非 Reactor模式的老版本。Spring Cloud Gateway使用的 Webflux中的 reactor-netty响应式编程组件,底层使用了 Netty通讯框架

Spring Cloud Gateway的目标提供统-的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流

主要特点

作用:反向代理,鉴权,流量控制,熔断,日志监控

  • 基于 Spring Framework5, Project Reactor和 Spring Boot2.0进行构建
  • 动态路由:能够匹配任何请求属性
  • 可以对路由指定 Predicate(断言)和 Filter(过滤器)
  • 集成 Hystrix的断路器功能
  • 集成 Spring Cloud服务发现功能
  • 请求限流功能
  • 支持路径重写

三大核心概念

Route(路由)

路由是构建网关的基本模块,它由 ID,目标URI,一系列的断言和过滤器组成,如果断言为 true 则匹配该路由

Predicate(断言)

开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

Filter(过滤)

指的是 Spring框架中 Gateway Filter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改

web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制,predicate就是我们的匹配条件,而 Filter ,就可以理解为个无所不能的拦截器有了这两个元素,再加上目标 uri 就可以实现一个具体的路由了



客户端向 Spring Cloud Gateway 发出请求,然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web handler,Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回,过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前("pre")或之后("post")执行业务逻辑

Filter在"pre"类型的过滤器可以做参数校验、权限校验、流量监控、日志输岀、协议转换等,在"post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用

路由配置

  1. 创建一个新的 module
  2. 导入 GateWay 依赖
<!-- Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
  1. 配置路由映射
  • 第一种配置方式:在配置文件 yml 中配置
server:
port: 9527 spring:
application:
name: GateWay-Service
cloud:
gateway:
routes:
# 路由的 ID,没有固定规则但要求唯一,建议配合服务名
- id: payment-route1
# 匹配后提供服务的路由地址
uri: http://localhost:8001
# 断言,路径相匹配的进行路由
# 配置服务端的方法路径
predicates:
- Path=/payment/query/** - id: payment-route2
uri: http://localhost:8001
predicates:
- Path=/payment/discovery/** # Eureka
eureka:
client:
# 表示是否将自己注册到 EurekaServer
register-with-eureka: true
# 是否从 EurekaServer 抓取已有的注册信息
# 单节点无所谓,集群必须设置为 true 才能配合 ribbon 使用
fetch-registry: true
service-url:
# 单机版
# defaultZone: http://localhost:7001/eureka/
# 集群版
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
instance:
hostname: GateWay-Service

  • 第二种配置方式:自定义配置文件
@Configuration
public class GateConfig { /**
* 测试通过网关 跳转到 百度新闻 的页面 http://news.baidu.com/guonei
* 配置了一个 id 为 payment-route3 的路由规则
* 当访问地址为 http://localhost:9527/guonei 会自动转发到 http://news.baidu.com/guonei
* @param routeLocatorBuilder
* @return
*/
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder){
return routeLocatorBuilder.routes()
.route( "payment-route3",r -> {
return r.path("/guonei")
.uri("http://news.baidu.com/guonei");
})
.build();
}
}

动态路由

默认情况下 Gateway会根据注册中心注册的服务列表,以注册中心上微服名为路径创建动态路由进行转发,从而实现动态路由的功能

配置 yml 配置文件

需要注意的是 uri 的协议为lb,表示启用 Gateway的负载均衡功能

lb://service Name 是spring cloud gateway在微服务中自动为我们创建的负载均衡uri

spring:
application:
name: GateWay-Service
cloud:
gateway:
discovery:
locator:
# 开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
routes:
# 路由的 ID,没有固定规则但要求唯一,建议配合服务名
- id: payment-route1
# 匹配后提供服务的路由地址
# uri: http://localhost:8001 不能写死
# 匹配 服务端 的路由地址,就是微服务名
uri: lb://provider-payment-service
# 断言,路径相匹配的进行路由
# 配置服务端的方法路径
predicates:
- Path=/payment/lb/** - id: payment-route2
uri: lb://provider-payment-service
predicates:
- Path=/payment/query/**

开启两个服务端8001和8002

实现了动态路由,可以测试到此时端口可以互相切换

Predicate使用

当开启路由网关时



SpringCloud Gateway 将路由匹配作为 Spring WebFlux HandlerMapping基础架构的部分

SpringCloud Gateway 包括许多内置的 RoutePredicate 工厂。所有这些Predicate都与HTTP请求的不同属性匹配,多个Route Predicate工厂可以进行组合

Spring Cloud Gateway创建 Route对象时,使用 RoutePredicate Factory创建 Predicate对象, Predicate对象可以赋值给Route. Spring Cloud Gateway包含许多内置的 Route predicate factories

所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and组合

常用的 Route Predicate
After

路由规则可以匹配一个时间,设置在{arg}之后,当请求的时间在配置时间之后,才会交给 route 去处理

spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2021-01-20T17:42:47.789-07:00[China/Shanghai]
Before

路由规则可以匹配一个时间,设置在{arg}之前,当请求的时间在配置时间之前,才会交给 route 去处理

spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Before=2021-01-20T17:42:47.789-07:00[China/Shanghai]
Between

路由规则可以匹配一个时间,设置在{arg}之间,当请求的时间在配置时间之间,才会交给 route 去处理

spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2021-01-20T17:42:47.789-07:00[China/Shanghai], 2021-01-21T17:42:47.789-07:00[China/Shanghai]
Cookie

需要2个参数,一个是cookie名字,另一个是值,可以为正则表达式。它用于匹配请求中,带有该名称的cookie和cookie匹配正则表达式的请求

spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=name, zhangsan # 例
# 请求带有cookie名为name, cookie值为 zhangsan 的请求
# 将都会转发到uri为 https://example.org 的地址上 # curl 请求
# $ curl -H ‘Cookie:name=zhangsan’ localhost:8081
  • 不带cookie访问

  • 带cookie访问

Header

在上面的配置中,当请求的 Header 中有 X-Request-Id的header名,且header值为数字时,请求会被路由到配置的 uri

spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+ # 例
# $ curl -H ‘X-Request-Id:1’ localhost:8081

Host

需要一个参数即hostname,它可以使用 . 或者 * 等去匹配host。这个参数会匹配请求头中的host的值,一致,则请求正确转发

spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org # 如果请求的主机标头的值为
www.somehost.org
或 beta.somehost.org
或 www.anotherhost.org
# 则此路由匹配
# curl 请求
# curl -H ‘Host:www.adou.com’ localhost:8081

Method

如果请求方法是GET或POST,则此路由匹配

spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
Path

当请求路径满足 /red/** ,则会经过 route 到达 https://example.org

spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/**
Query

也可以只填一个参数,填一个参数时,则只匹配参数名,当请求中请求参数包含 green,则会经过 route 到达 https://example.org

spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
- Query=color, green
# 配置了请求中含有参数color,并且color的值匹配green.,则请求命中路由
# curl 请求
# $ curl localhost:8081?color=green
RemoterAddr

请求远程地址,则会经过 route

spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24 # 如果请求的远程地址是 192.168.1.10 ,则此路由匹配
Weight

权重采用两个参数匹配 group 和 weight,当达成条件则会路由转发

spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2 # 这条路线会将大约80%的流量转发到 weighthigh.org
# 将大约20%的流量转发到 weightlow.org

说白了, Predicate就是为了实现一组匹配规则,让请求过来找到对应的 Route进行处理

Filter使用

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用

Spring Cloud Gateway内置了多种路由过滤器,他们都由 GatewayFilter 的工厂类来产生

种类:GateWayFilterGlobalFilter

自定义过滤器

自定义全局GlobalFilter

主要继承两个接口:GlobalFilter,Ordered

作用:全局日志记录,统一网关鉴权等等

@Component
@Slf4j
public class LogGateWayFilter implements GlobalFilter, Ordered { @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求的参数
String username = exchange.getRequest().getQueryParams().getFirst("username");
if (username == null){
log.info("用户名为空,找不到该用户");
// 设置状态码
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
// 返回
log.info("进入拦截器");
return chain.filter(exchange);
} /**
* 加载过滤器的顺序
* @return
*/
@Override
public int getOrder() {
return 0;
}
}

SpringCloud(四)GateWay网关的更多相关文章

  1. SpringCloud:gateway网关模块启动报错

    1.错误信息 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with na ...

  2. SpringCloud使用GateWay网关前端请求请求跨域处理

    增加配置类 CorsConfig.java import org.springframework.context.annotation.Bean; import org.springframework ...

  3. Spring Cloud gateway 网关四 动态路由

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

  4. SpringCloud + Consul服务注册中心 + gateway网关

    1  启动Consul 2  创建springcloud-consul项目及三个子模块 2.1 数据模块consul-producer 2.2 数据消费模块consul-consumer 2.3 ga ...

  5. 实战四:Gateway网关作全局路由转发

    Gateway网关的作用主要是两个:路由转发,请求过滤.此篇讲的是路由转发,下篇介绍请求过滤. 一,创建网关module,添加依赖 1,new -> module -> maven 或直接 ...

  6. Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制

    一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...

  7. JHipster生成微服务架构的应用栈(四)- 网关微服务示例

    本系列文章演示如何用JHipster生成一个微服务架构风格的应用栈. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用栈名称:appstack 认证微服务: uaa 业 ...

  8. 微服务SpringCloud之GateWay路由

    在前面博客学习了网关zuul,今天学下spring官方自带的网关spring cloud gateway.Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长连接,如 WebSo ...

  9. Spring Cloud gateway 网关服务二 断言、过滤器

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

随机推荐

  1. 【资源下载】Linux下的Hi3861一站式鸿蒙开发烧录(附工具)

    下载附件 2021春节前夕,华为发布了 HUAWEI DevEco Device Tool 2.0 Beta1,整体提供了异常强大的功能.得知消息后,我在第一时间带着无比兴奋的心情下载尝鲜,但结果却是 ...

  2. 2.2 Python3基础-基本数据类型

    >>返回主目录 源代码 # 基本数据类型 # Number类型:如何查看变量的数据类型? name = 'Portos' print(type(name)) # 结果:str print( ...

  3. ORM框架 和 面向对象编程

    ORM框架: 1.SQLAlchemy:  - 作用   1.提供简单的规则   2.自动转换成SQL语句  - DB first/code first   DB first: 手动创建数据库以及表  ...

  4. 基于Linux的tty架构及UART驱动详解

    更多嵌入式Linux原创,请关注公众号:一口Linux 一.模块硬件学习 1.1. Uart介绍 通用异步收发传输器(Universal Asynchronous Receiver/Transmitt ...

  5. JAVA-标识符、变量、数据类型

    标识符和关键字 ​ 所有的标识符否应该以字母a ~ z和 A ~Z ,美元符($).下划线(_)开始. ​ 首字符之后可以是字母a ~ z和 A ~Z ,美元符($).下划线(_)的任意字符组合. 注 ...

  6. Python3+pygame实现的flappy bird游戏,代码完整,还有音乐

    之前一直在手机上玩flappy bird游戏,闲暇时间就编写了一个 是采用python3+pygame模块制作而成的,运行效果非常流畅,会让你大吃一惊哦哈哈 一.运行效果展示 下载游戏之后,注意在自己 ...

  7. kali Linux树莓派的完整配置,以及python环境的配置

    kali Linux树莓派3b+的环境配置,以及python开发环境的配置 首先需要正确组装树莓派的硬件,所需:一块8G以上的内存卡,(一般情况下淘宝购买的时候都会选择一个,需要一个稳定的电源输出,防 ...

  8. sitemesh简单介绍

    SiteMesh 是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的. Sitemesh是由一个基于Web页面布局.装饰以及与现存Web应用整合的框架. 它能帮 ...

  9. android分析之Thread类

    线程与线程类要区分开来. 抽象来说,线程是CPU调度的最小单位,但是线程总要执行代码,这个代码就在线程类里说明(即Thread类).无论如何,Thread只是一个类,但其功能就是"启动一个线 ...

  10. Shuffle Card HDU - 6707

    题目链接:https://vjudge.net/problem/HDU-6707 题意:给你一个数组a[ ](a[1]=1,a[2]=2.....a[n]=n),然后m次操作,每次把那个数拿到最前面去 ...