SpringCloud Gateway

cloud笔记第一部分

cloud笔记第二部分Hystrix

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

为了提升网关性能,Gateway是基于WebFlux实现的,而WebFlux框架是使用了高性能的Reactor模式通信框架Netty

Spring Cloud Gateway的目标是提供一种统一的路由方式且基于Filter的方式实现网关的基本功能,例如:安全,监控/指标,限流。

Zull的工作模式与Gateway的对比

Zuul采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。

这种模式的缺点是:当在并发不高的场景下这种模型是适用的,但是一旦高并发,线程数会大幅度增加,同时线程的创建销毁这个过程消耗的资源又是昂贵的,严重影响请求的处理时间,在一些简单的业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发请求,这种业务场景下servlet模型没有优势,所以Zuul1版本是基于servlet上的阻塞式处理模型,因此无法解决这种弊端。

在Servlet3.1之后有了异步非阻塞的支持。而WebFlux是一个典型的非阻塞的异步框架,他的核心是基于Reactor的相关API实现的。相对于传统的Web框架来说,它可以运行在Netty,Undertow以及支持Servlet3.1的容器上。

SpringWebFlux是Spring5引入的新的响应式的框架,区别在于SpringMVC,他不需要依赖Servlet API,是完全的异步非阻塞,并基于Reactor来实现响应式流规范。

Route(路由)

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

Predicate(断言)

开发人员可以匹配HTTP请求中的所有内容,如果请求与断言相匹配则进行路由。

Filter(过滤)

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

总结:客户端向Gateway发出请求,然后在Gateway Handle Mapping中找到与请求相匹配的路由,将其发送到gateway web Hnadle。

Handle再通过指定的过滤器链来将请求发送到我们实际的服务之星业务逻辑,然后返回。过滤器可以在服务端接收请求前过滤,也可以在服务端向客户端发送响应后过滤。

请求到达服务端前可以做:参数校验、权限校验、流量控制、日志输出、协议转换等。

在服务端业务处理之后可以对响应的内容。头部进行修改,日志的输出,流量的监控都有重要作用。

GateWay的配置方式

1、在配置文件中直接配置

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/** # 断言,路径相匹配的进行路由 eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka

在使用Gateway做路由转发的功能时,需要引入的依赖。

  <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>org.xzq.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>

需要注意的是,不需要引入web和actual,否则会启动失败。

这时候访问http://localhost:8001/payment/get/1001,查询订单,同时也能通过

http://localhost:9527/payment/get/1001访问到1001的订单信息。这就是当访问的URI符合配置文件中设置的predicate,就能通过Gateway转发。

2、编写GatewayConfig配置类

@Configuration
public class GatewayConfig { @Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
// routes_id=route_guonei uri= http://news.baidu.com/guonei ; predicate Path=/guonei
routes.route("route_guonei",r->r.path("/guonei")
.uri("http://news.baidu.com/guonei"))
.build();
return routes.build();
}
}

访问http://localhost:9527/guonei,会被路由到http://news.baidu.com/guonei

通过微服务名实现动态路由

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

开启从注册中心动态创建路由的功能,利用微服务名进行路由

discovery:
locator:
enabled: true

server:
port: 9527 spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由 - id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由 eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka

常用的Predicate属性

官方文档

  • After Route:在predicates下设置时间轴,在这个符合时间轴之后的请求才能路由。类型是ZoneDateTime
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
  • Before Route:匹配指定时间之前的请求,类型是ZoneDateTime。
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
  • Between Route:在指定时间间隔内发起的请求才能匹配成功。predicate才是true。
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
  • Cookie Route:请求中需要包含指定的cookie才能匹配成功。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
  • Header Route:请求头参数中要包含指定键值对,否则不匹配。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
  • Host Route:根据主机名进行匹配。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
  • Method Route: 符合指定的请求方法才能匹配成功。
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
  • Path Route: 符合请求路径,路径中可以使用通配符。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/**
  • Query Route: 包含指定参数才能匹配成功。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
  • Weight Route:根据请求的流量大小转发不同的服务
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%的请求流量转发到https://weighthigh.org,将20%的流量转发到https://weightlow.org。

  • Remote Route:匹配IP地址才能路由。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24

自定义过滤器

自定义过滤器实现GlobalFilterOrdered接口,重写方法。

@Component
@Slf4j
public class MyLogGatewayFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 自定义过滤器,打印日志,如果请求参数中uname=null或者没有uname属性,不会放行请求 log.info("----- com in MyLogGatewayFilter -----");
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("----- uname 不能为空 -----");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
} @Override
public int getOrder() {
return 0;
}
}

如果请求参数没有加uname或者uname=null都不会放行请求。

SpringCloud Gateway快速入门的更多相关文章

  1. API网关才是大势所趋?SpringCloud Gateway保姆级入门教程

    什么是微服务网关 SpringCloud Gateway是Spring全家桶中一个比较新的项目,Spring社区是这么介绍它的: 该项目借助Spring WebFlux的能力,打造了一个API网关.旨 ...

  2. 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)

    [原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...

  3. SpringCloud Gateway入门

    本文是介绍一下SpringCloud Gateway简单路由转发使用. SpringCloud Gateway简介 SpringCloud是基于Spring Framework 5,Project R ...

  4. 万字长文:SpringCloud gateway入门学习&实践

    官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/# ...

  5. OpenStack云计算快速入门之二:OpenStack安装与配置

    原文:http://blog.chinaunix.net/uid-22414998-id-3265685.html OpenStack云计算----快速入门(2) 该教程基于Ubuntu12.04版, ...

  6. 笔记:Spring Cloud Zuul 快速入门

    Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...

  7. Spring Cloud Zuul 快速入门

    Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...

  8. 使用springcloud gateway搭建网关(分流,限流,熔断)

    Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...

  9. 体验SpringCloud Gateway

    Spring Cloud Gateway是Spring Cloud技术栈中的网关服务,本文实战构建一个SpringCloud环境,并开发一个SpringCloud Gateway应用,快速体验网关服务 ...

随机推荐

  1. pymysql出现的问题

    pymysql的使用bug 每次执行sql语句(增删改查)必须commit提交 当重复执行相同slq语句时,如果不commit,fetchall的结果会是上次执行的结果 或者打开pymysql的自动提 ...

  2. Linux查看、开启、关闭防火墙操作

    一.防火墙区别 CentOS6自带的防火墙是iptables,CentOS7自带的防火墙是firewall. iptables:用于过滤数据包,属于网络层防火墙. firewall:底层还是使用 ip ...

  3. Go语言(1)——程序结构

    程序结构 基础部分仅仅列举和其他语言不一样的地方(C语言为例). 声明 Go语言有四个主要声明:var.const.type.func,类似于C语言中的变量,常量,结构体和函数. package ma ...

  4. html 02-浏览器的介绍

    02-浏览器的介绍 #常见的浏览器 浏览器是网页运行的平台,常见的浏览器有谷歌(Chrome).Safari.火狐(Firefox).IE.Edge.Opera等.如下图所示: 我们重点需要学习的是 ...

  5. vue第十三单元(指令的作用,指令的钩子函数)

    第十三单元(指令的作用,指令的钩子函数) #课程目标 1.了解自定义指令的应用场景 2.掌握自定义全局和局部指令 3.掌握指令的钩子函数 #知识点 #一.认识自定义指令 除了核心功能默认内置的指令 ( ...

  6. 使用BulkLoad恢复hbase数据

    问题: hbase 集群启动不了,maste一直在初始化,数据面临丢失风险. 解决: 把hbfs上 /hbase 目录移走 改名为/hbase-bak 删除zk上的数据,重新建立一个新的hbase集群 ...

  7. matplotlib的学习15-次坐标轴

    import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 0.1) y1 = 0.05 * x**2 y2 = - ...

  8. .netcore3.1——应用AutoMapper

    多层架构中存在多种模型,如视图模型ViewModel,数据传输对你DTO,ORM对象等,这些数据在层与层之间进行传输必须涉及类型之间的转换. AutoMapper是一个对象-对象映射器,作用是通过设置 ...

  9. [.NET] - 初步认识AutoMapper

    初步认识AutoMapper AutoMapper 初步认识AutoMapper 前言 手动映射 使用AutoMapper 创建映射 Conventions 映射到一个已存在的实例对象   前言 通常 ...

  10. double 转为long类型

    System.out.println(new Double(234314.999999999).longValue());//234314  System.out.println(new Double ...