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. AcWing 195. 骑士精神

    双向BFS (广搜) \(O(8 ^ 7)\) 看到没有双向BFS的题解我就过来了 这道题也可以用双向\(BFS\)来做,时间复杂度与\(IDA*\)不相上下. 双向\(BFS\)的实现有多种: 把初 ...

  2. Java8的Lambda表达式,你会不?

    目录 理解Lambda 基础语法 函数式接口 常用的函数式接口 消费型接口 供给型接口 断言型接口 函数型接口 方法引用 数组引用 构造器引用 总结 参考阅读 理解Lambda Lambda表达式可以 ...

  3. 用列表+for循环生成乘法口诀表

    1 # 结合一下列表生成, 准备设计乘法表 2 # numlist = [1,2,3,4,5] 3 # [pow(i,3) for i in numlist] 4 # ## [1, 8, 27, 64 ...

  4. SpringDataJPA 多对多的查询

     主要的结构目录: 创建Role.java package cn.itcast.domain; import javax.persistence.*; import java.util.HashSet ...

  5. post 和php://input

    $_POST['paramName'] 获取通过表单(multipart/form-data)提交的数据.但有时客户端会直接将请求数据以字符串的形式都放到 body 里传递过来,那么服务端就需要使用  ...

  6. 记一次真实的webpack优化经历

    前言 公司目前现有的一款产品是使用vue v2.0框架实现的,配套的打包工具为webpack v3.0.整个项目大概有80多个vue文件,也算不上什么大型项目. 只不过每次头疼的就是打包所耗费的时间平 ...

  7. 作为Java新手,如何才能快速的看透一个Java项目?

    前言 技术学习是一个总结.纠错.触类旁通的过程,而不是单纯重复练习的过程,如果你问一个做过5年以上Java的老码农,他们很多人都会有很强的"搬砖感",这种"搬砖感&quo ...

  8. 回顾 2020 年 GitHub 的大事件,你知道多少?

    作者:HelloGitHub-小鱼干 这里是 HelloGitHub 出品的年度盘点系列,本期我们将盘点 GitHub 在 2020 发生的大事件,回顾一下今年 GitHub 给我们带来了那些惊喜.故 ...

  9. Web项目Bin目录下的文件改动会引发Application_End事件,IIS会回收线程

    原博文 https://blog.csdn.net/caca95/article/details/85284309 处理方法 Web项目Bin目录下的文件改动会引发Application_End事件, ...

  10. 函数进阶· 第3篇《常用内置函数filter()、map()、zip(),怎么用的呢?》

    坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 由于微信公众号推送改为了信息流的形式,防止走丢,请给加个星标 ,你就可以第一时间接收到本公众号的推送! ...