1、概述

zuul 1.x:https://github.com/Netflix/zuul/wiki

Spring Cloud GateWay官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

1.1 GateWay是什么?

Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单有效的、统一的 API 路由管理方式。

Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,其目标是替代 Netflix Zuul,它不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等。

Spring Cloud Gateway 依赖 Spring Boot 和 Spring WebFlux,基于 Netty 运行。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。

一句话总结:Gateway使用的是Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。

1.2 GateWay的作用

  • 反向代理
  • 鉴权
  • 浏览控制
  • 熔断
  • 日志监控

1.3 网关GateWay在微服务中的位置

1.4 Gateway的三大核心概念

  • Route(路由)

    Route 是最核心的路由元素,它定义了ID,目标URI ,predicates的集合与filter的集合,如果Predicate聚合返回真,则匹配该路由

  • Predicate(断言)

    基于java8的函数接口Predicate,其输入参数类型ServerWebExchange,其作用就是允许开发人员根据当前的http请求进行规则的匹配,比如说http请求头,请求时间等,匹配的结果将决定执行哪种路由

  • Filter(过滤)

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

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

1.5 GateWay的工作流程

官网的工作流程图:

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.

客户端向springcloudgateway发出请求。

如果在Gateway Handler Mapping(网关处理程序映射)中找到与请求相匹配的路由,则将其发送到Gateway Web Handler(网关Web处理程序)。

Handler再通过指定的过滤器链来将请求发送到我们实际的服务中执行业务逻辑,然后返回。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前(pre)和之后(post)执行业务逻辑。

Filter在“Pre”类型的过滤器中可以做参数校验,权限校验,流量监控,日志输出和协议转换等操作;在“Post”类型的过滤器中可以做响应内容,响应头的修改,日志的输出,流量监控等操作。Filer的功能强大。

2、入门案例

2.1 创建模块cloud-gateway-gateway9527

2.1.1 pom.xml

<?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>springcloud2020</artifactId><groupId>com.zdw.springcloud</groupId><version>1.0-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><!--gateway无需web和actuator,如果有的话启动会报错--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--引入自定义的公共包,回用到里面的实体--><dependency><groupId>com.zdw.springcloud</groupId><artifactId>cloud-api-common</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

2.1.2 application.yml配置

server:port: 9527spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由routes:- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名#匹配后提供服务的路由地址uri: http://localhost:8001predicates:- Path=/payment/get/** # 断言,路径相匹配的进行路由- id: payment_route2uri: http://localhost:8001predicates:- Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:instance:hostname: cloud-gateway-serviceclient:fetch-registry: trueregister-with-eureka: trueservice-url:# 单击版defaultZone: http://localhost:7001/eureka# 集群版# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

我们现在是要在服务 cloud-provider-payment8001 外面包上一层9527的网关,所以我们配置的路由是针对cloud-provider-payment8001服务的,等会测试的时候,需要把cloud-provider-payment8001启动。

2.1.3 主启动类

package com.zdw.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;/*** @author ZDW* @create 2020-08-19 16:00*/
@SpringBootApplication
//作为eureka的客户端注册进eureka中
@EnableEurekaClient
public class GatewayMain9527 {public static void main(String[] args) {SpringApplication.run(GatewayMain9527.class,args);}
}

2.1.4 测试

1、启动cloud-eureka-server7001服务

2、启动cloud-provider-payment8001服务

3、启动cloud-gateway-gateway9527服务

浏览器访问:

添加网关前,直接访问8001:http://localhost:8001/payment/get/1 是可以访问到数据的

添加网关后,直接访问9527:http://localhost:9527/payment/get/1 也是可以访问成功的

通过配置路由和断言,在8001的外面包了一层9527的网关,对外暴露的是9527的地址。

2.2 通过Java代码配置路由

在上面的application.yml文件中,我们是配置了路由的,不过除了这种方式外,还支持通过Java配置类的方式来进行路由配置:

业务需求:通过9527网关访问到外网的百度新闻网址

2.2.1 配置类:GatewayConfig

package com.zdw.springcloud.config;import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author ZDW* @create 2020-08-19 16:18* 通过Java配置类来进行路由的配置*/
@Configuration
public class GatewayConfig {/*** 配置了一个id为route-name的路由规则* 当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baidu.com/guonei* @param builder* @return*/@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder) {RouteLocatorBuilder.Builder routes = builder.routes();routes.route("path_route_zdw1",r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();return routes.build();}@Beanpublic RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {RouteLocatorBuilder.Builder routes = builder.routes();routes.route("path_route_zdw1",r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build();return routes.build();}
}

2.2.2 测试

重启服务:cloud-gateway-gateway9527,然后浏览器访问:http://localhost:9527/guonei 会被路由到百度:http://news.baidu.com/guonei

3、通过服务名实现动态路由

在上面的application.yml中,我们配置的路由的uri是:uri: http://localhost:8001,如果服务是多个,比如有8001和8002,此时我们这里写的8001,那么就只会把请求转发到8001,这样明显不太好,无法实现负载均衡。所以接下来,要通过配置,动态的实现路由,可以把请求转发到8001和8002两个服务。

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

3.1 修改application.yml

server:port: 9527spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由routes:- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名#匹配后提供服务的路由地址#uri: http://localhost:8001# lb是固定的,表示的是协议lb,表示启用Gateway的负载均衡功能,# cloud-payment-service是cloud-provider-payment8001和cloud-provider-payment8002注册到eureka注册中的服务名称uri: lb://cloud-payment-servicepredicates:- Path=/payment/get/** # 断言,路径相匹配的进行路由- id: payment_route2#uri: http://localhost:8001uri: lb://cloud-payment-servicepredicates:- Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:instance:hostname: cloud-gateway-serviceclient:fetch-registry: trueregister-with-eureka: trueservice-url:# 单击版defaultZone: http://localhost:7001/eureka# 集群版# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

3.2 测试

1、启动cloud-eureka-server7001服务

2、启动cloud-provider-payment8001服务和cloud-provider-payment8002服务(这两个服务配置的是eureka的单机版)

3、启动cloud-gateway-gateway9527服务

浏览器访问:http://localhost:9527/payment/lb 可以看到8001和8002交替进行

4、Predicate

Predicate 是基于java8的函数接口Predicate,其输入参数类型ServerWebExchange,其作用就是允许开发人员根据当前的http请求进行规则的匹配,比如说http请求头,请求时间等,匹配的结果将决定执行哪种路由;

在启动9527服务的日志中,可以看到:

可以看到这些都是路由谓词工厂 (Route Predicate Factories)的相关谓词。

4.1 Route Predicate Factories是什么

Spring Cloud Gateway的路由谓词工厂 (Route Predicate Factories),路由谓词工厂的作用是:符合Predicate的条件,就使用该路由的配置,否则就不管。

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。
Spring Cloud Gateway包括许多内置的Route PredicateI。所有这些Predicate都与HTTP请求的不同属性匹配。多个RoutePredicate.工厂可以进行组合。
Spring Cloud Gateway创建Route对象时,使用RoutePredicateFactory创建Predicate对象, Predicate对象可以赋值给Route。 Spring Cloud Gateway包含许多内置的Route Predicate Factories。
所有这些谓词都匹配HTTP请求的不同属性,多种谓词工厂可以互相组合,并通过逻辑and。

4.2 常用的Route Predicate Factories

参考:https://www.cnblogs.com/bjlhx/p/9785926.html

4.2.1 After Route Predicate

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:# 这个是美国时区,表示要在这个时间只后,上面的路由才会生效- After=2017-01-20T17:42:47.789-07:00[America/Denver]

上面- After配置的时间是美国时间,可以使用下面的代码得到当前时区的时间:

System.out.println(ZonedDateTime.now());  //2020-08-19T17:01:44.755+08:00[Asia/Shanghai]

其他的省略

5、Filter

可以参考:https://blog.csdn.net/forezp/article/details/85057268

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂 类来产生。

5.1 常用的Filter

5.1.1 单个路由的gateway filter

它在配置文件中的写法同predict类似;

过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。过滤器可以限定作用在某些特定请求路径上。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。

GatewayFilter工厂同上一篇介绍的Predicate工厂类似,都是在配置文件application.yml中配置,遵循了约定大于配置的思想,只需要在配置文件配置GatewayFilter Factory的名称,而不需要写全部的类名,比如AddRequestHeaderGatewayFilterFactory只需要在配置文件中写AddRequestHeader,而不是全部类名。在配置文件中配置的GatewayFilter Factory最终都会相应的过滤器工厂类处理。

官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

5.1.2 针对于所有路由的global gateway filer

GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。

官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#global-filters

5.2 自定义全局GlobalFilter

自定义的Filter需要实现GlobalFilter和Ordered接口;

作用:全局日志记录和统一网关鉴权等一系列操作;

5.2.1 需求

判断请求中是否有参数username,如果没有,就提示非法用户

5.2.2 自定义MyLogGatewayFilter

package com.zdw.springcloud.filter;import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Date;/*** @author ZDW* @create 2020-08-19 17:38*/
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {@Overridepublic 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);}/*** 加载过滤器的顺序,数字越小,优先级越高*/@Overridepublic int getOrder() {return 0;}
}

5.2.3 测试

1、启动cloud-eureka-server7001服务

2、启动cloud-provider-payment8001服务和cloud-provider-payment8002服务(这两个服务配置的是eureka的单机版)

3、启动cloud-gateway-gateway9527服务

浏览器访问:http://localhost:9527/payment/lb ,没有任何响应,可以看到后台打印了:*****用户名为null,非法用户,o(╥﹏╥)o ,这说明已经被我们的过滤器把请求拦截了

浏览器访问:http://localhost:9527/payment/lb?uname=z3 可以得到正常的响应,端口8001和8002交替显示

}

/*** 加载过滤器的顺序,数字越小,优先级越高*/
@Override
public int getOrder() {return 0;
}

}


### 5.2.3 测试1、启动cloud-eureka-server7001服务2、启动cloud-provider-payment8001服务和cloud-provider-payment8002服务(这两个服务配置的是eureka的单机版)3、启动cloud-gateway-gateway9527服务浏览器访问:http://localhost:9527/payment/lb  ,没有任何响应,可以看到后台打印了:*****用户名为null,非法用户,o(╥﹏╥)o ,这说明已经被我们的过滤器把请求拦截了浏览器访问:http://localhost:9527/payment/lb?uname=z3 可以得到正常的响应,端口8001和8002交替显示

SpringCloud11-GateWay网关相关推荐

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

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

  2. SpringCloud微服务架构之,Hystrix 熔断器,Gateway 网关

    Hystrix 概述 Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务.第三方库,防止出现级联失败(雪崩). pom依耐 <!-- hystrix -->&l ...

  3. Gateway网关-网关作用介绍

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

  4. SpringCloud Greenwich(四)注册中心之eureka、Zuul和 gateway网关配置

    本项目是搭建基于eureka注册中心的springcloud,使用zuul网关和gateway网关 一.框架搭建 (1)项目结构 eureka-server  eureka注册中心 micro-ser ...

  5. SpringCloud Greenwich(三)注册中心之zookeeper、Zuul和 gateway网关配置

    本项目是搭建基于zookeeper注册中心的springcloud,使用zuul网关和gateway网关 一.框架搭建 (1)项目结构 micro-service  服务提供者 zuul-gatewa ...

  6. SpringCloud Greenwich(二)注册中心之consul、Zuul和 gateway网关配置

    本项目是搭建基于consul注册中心的springcloud,使用zuul网关和gateway网关 一.框架搭建 (1)项目结构 micro-service  服务提供者 zuul-gateway  ...

  7. SpringCloud Greenwich(一)注册中心之nacos、Zuul和 gateway网关配置

    本项目是搭建基于nacos注册中心的springcloud,使用zuul网关和gateway网关. 一.框架搭建 (1)项目结构 micro-service  服务提供者 zuul-gateway  ...

  8. spring cloud gateway 网关_微服务网关Spring Cloud Gateway全搞定

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

  9. SpringCloud Hoxton版微服务- Gateway网关

    Gateway网关 一.Gateway概念 二.三大核心概念 1.Route (路由) 2.Predicate (断言) 3.Filter (过滤) 三.工作流程图 四.工程搭建 1.新建Gatewa ...

  10. Spring Cloud微服务之Gateway网关(十三)

    Gateway网关 一.网关基本概念 1.API网关介绍 2.Spring Cloud Gateway 3.Spring Cloud Gateway核心概念 4.我们在没有网关下,怎么解决客户端直接与 ...

最新文章

  1. 怎么理解ASM中的Failgroup
  2. Postman最被低估的功能,自动化接口测试效率简直无敌
  3. JAVA---AWT 图形绘制
  4. javadrawstring设置字符大小_LaTex学术写作——编辑文档格式 设置论文标题与摘要...
  5. CentOS 6.3下rsync服务器的安装与配置[转]
  6. a标签在ie6和ie7下面换行显示问题解析
  7. python嵌入shell代码_大家一起学python-Python基础1
  8. php header 跳转 ie问题
  9. 对元素组按关键字字典序排序
  10. 添加ClearWindow.py文件实现IDLE的清屏功能
  11. 官方下载:slf4j-nop.jar slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar
  12. shell php的守护进程,实例详解shell编写守护进程的方法
  13. C++内存管理之shared_ptr
  14. steam遇到错误代码解决方案
  15. 测试电脑整机功耗软件,最真实的耗电!PConline权威整机功耗评测
  16. 模拟信号和数字信号的区别和特点
  17. Windows10 下面一个非常快速而精悍的看图软件 - IrfanView
  18. 追求技术之美:云计算开发者的自我修养
  19. iOS音视频开发七:视频采集
  20. JavaScript高级编程设计(第三版)——第二章:在html中使用javaScript

热门文章

  1. Pyinstaller打包
  2. 游百望山(记于17.09.05)
  3. 企业级和个人苹果帐号AppleId申请
  4. springboot启动类
  5. 论文笔记 General Advantage Estimation(GAE)
  6. Servlet共享数据域cookie、session ;监听器;过滤器
  7. springboot基于web儿童教育网站111123
  8. php运行模式cgi,修改DirectAdmin面板PHP运行模式为CGI
  9. 分享 | 视觉无监督学习新范式:MAE
  10. .NET CORE敏捷开发框架,企业信息化自主化解决方案