【SpringCloud】Gateway新一代网关

【SpringCloud】Gateway新一代网关,第1张

概述Gateway新一代网关 #概述简介 ##官网 ###上一代zuul 1.x https://github.com/Netflix/zuul/wiki ###当前gateway https://clo

Gateway新一代网关

概述简介官网上一代zuul 1.x

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

当前gateway

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/HTML/

是什么概述

Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的ZuuI网关;
但在2.x版本中,zuul的升级一 直跳票, SpringCloud最后自己研发了一个网关替代Zuul,那就是SpringCloud Gateway
一句话: gateway是 原zuul1.x版的替代

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

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

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

一句话:

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

源码架构

能干嘛反向代理鉴权流量控制熔断日志监控.....微服务架构中网关在哪里

有Zuul了怎么又出来gateway我们为什么选择Gateway?1.netflix不太靠谱,zuul2.0一直跳票,迟迟不发布

一方面因为Zuul1.0已经进 入了维护阶段,而且Gateway是 SpringCloud团队研发的,是亲儿子产品,值得信赖。而且很多功能Zuul都没有用起来也非常的简单便捷。

Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的Zuul 2.x,但Spring Cloud貌似没有整合计划。而且Netflix相关组件都宣布进入维护期;不知前景如何?

多方面综合考虑Gateway是很理想的网关选择。

2.SpringCloud Gateway具有如下特性

Spring Cloud Gateway具有如下特性:

基于Spring Framework 5,Project Reactor和Spring Boot 2.0进行构建; τ动态路由:能够匹配任何请求属性;可以对路由指定Predicate (断言)和Filter (过滤器) ;集成Hystrix的断路器功能;集成Spring Cloud服务发现功能;易于编写的Predicate (断言)和Filter (过滤器) ;请求限流功能;支持路径重写。3.SpringCloud Gateway与Zuul的区别

Spring Cloud Gateway与Zuul的区别
在SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix 提供的Zuul:

Zuul1.x,是一个基于阻塞I/ 0的API Gateway .Zuul 1.x 基于Servlet 2. 5使用阻塞架构它不支持任何长连接(如WebSocket) Zuul的设计模式和Nginx较像,每次I/ 0 *** 作都是从工作线程中选择一个执行, 请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul 用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul 的性能相对较差。Zuul 2.x理念更先进,想基于Netty非阻塞和支持长连接,但SpringCloud目前还没有整合。 Zuul 2.x的性能较Zuul 1.x有较大提升。在性能方面,根据官方提供的基准测试, Spring Cloud Gateway的RPS (每秒请求数)是Zuul的1.6倍。Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot2之上,使用非阻塞API。Spring Cloud Gateway还支持WebSocket,诅与Spring紧密集成拥有更好的开发体验Zuul1.x模型

Springcloud中所集成的Zuμ版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。

学过尚硅谷web中期课程都知道一个题目,Servlet的生命周期?servlet由servlet container进行生命周期管理。
container启动时构造servlet对象并调用servlet init()进行初始化;
container运行时接受请求,并为每个请求分配一个线程 (一般从线程池中获取空闲线程) 然后调用service()。
container关闭时调用servlet destory()销毁servlet;

上述模式的缺点:
servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发(此如抽风用jemeter压),线程数量就会上涨,而线程资源代价是昂贵的(. 上线文切换,内存消耗大)严重影响请求的处理时间。
在一些简单业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势

所以Zuul 1.X是基于servlet之上的一个阻塞式处理模型,即spring实现了 处理所有request请求的一个servlet (dispatcherServlet) 并由该servlet阻塞式处理处理。所以Springcloud Zuul无法摆脱servlet模型的弊端

Gateway模型WebFlux是什么

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.HTML#spring-webflux


说明:
传统的Web框架,此如说: struts2,springmvc等都是 基于Servlet API与Servlet容器基础之上运行的。
但是
在Servlet3.1之后有了异步非阻塞的支持。而WebFlux是一 个典型非阻塞异步的框架, 它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及 支持Servlet3.1的容器上。非阻塞式+函数式编程(Spring5必须让你使用java8)

Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于Spring MVC,它不需要依赖Servlet API,它是完全异步非阻塞的,并且基于Reactor来实现响应式流规范。

三大核心概念Route(路由)

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

Predicate(断言)

参考的是Java8的java.util.function.Predicate 开发人员可以匹配http请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

Filter(过滤)

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

总结


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

Gateway工作流程官网总结


客户端向Spring Cloud Gateway发出请求。然后在Gateway Handler MapPing中找到与请求相匹配的路由,将其发送到Gateway Web Handler。

Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( "pre” )或之后( "post" )执行业务逻辑。

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

我的理解:
gateway
先根据断言条件找到指定的微服务,再路由转发,过滤可以在路由转发前或转发后加一些自己的东西。

我认为网关是整合所有模块的不同端口,让他们对外暴露一个统一的端口来进行映射调用使用
uri就是整合的模块端口地址
predicated是模块里的方法映射地址
通过端口,我们可以直接选取方法映射地址来进行调用,而不用到其模块的信息。

核心逻辑

路由转发+执行过滤器链

入门配置新建Module

cloud-gateway-gateway9527

POM
<dependencIEs>    <dependency><!-- 引用自己定义的API通用包,可以使用Payment支付Entity -->        <groupID>com.eiletxIE.springcloud</groupID>        <artifactID>cloud-API-commons</artifactID>        <version>${project.version}</version>    </dependency>    <!--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>    <!--热部署-->    <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>
YML
server:  port: 9527spring:  application:    name: cloud-gatewayeureka:  instance:    hostname: cloud-gateway-service  clIEnt:    register-with-eureka: true    fetch-registry: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka/
业务类

主启动类
@SpringBootApplication@EnableEurekaClIEntpublic class GatewayMain9527 {    public static voID main(String[] args) {        SpringApplication.run(GatewayMain9527.class,args);    }}
9527网关如何做路由映射呢???cloud-provIDer-payment8001看看controller的访问地址getlb我们目前不想暴露8001端口,希望在8001外面套一层9527YML新增网关配置
server:  port: 9527spring:  application:    name: cloud-gateway  cloud:    gateway:      discovery:        locator:          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由      routes:        - ID: payment_route # 路由的ID,没有规定规则但要求唯一,建议配合服务名         #匹配后提供服务的路由地址          uri: http://localhost:8001          predicates:            - Path=/payment/get/** # 断言,路径相匹配的进行路由        - ID: payment_route2          uri: http://localhost:8001          predicates:            Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:  instance:    hostname: cloud-gateway-service  clIEnt:    fetch-registry: true    register-with-eureka: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka/
测试

启动7001

启动8001
cloud-provIDer-payment8001

启动9527

访问说明

添加网关前
http://localhost:8001/payment/get/31添加网关后
http://localhost:9527/payment/get/31yml配置说明

Gateway网关路由有两种配置方式:

在配置文件yaml中配置见前面的步骤代码中注入RouteLocator的Bean官网案例

百度国内新闻网站,需要外网

https://news.baIDu.com/guonei

自己写一个百度新闻业务需求

通过9527网关访问到外网的百度新闻网址

编码

cloud-gateway-gateway9527

业务实现

package com.eiletxIE.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 EiletXIE * @Since 2020/3/12 15:01 */@Configurationpublic class GatewayConfig {    /**     * 配置了一个ID为route-name的路由规则     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baIDu.com/guonei     * @param builder     * @return     */    @Bean    public RouteLocator customrouteLocator(RouteLocatorBuilder builder) {        RouteLocatorBuilder.Builder routes = builder.routes();        routes.route("path_route_eiletxIE",r -> r.path("/guonei")                        .uri("http://news.baIDu.com/guonei")).build();        return routes.build();    }    @Bean    public RouteLocator customrouteLocator2(RouteLocatorBuilder builder) {        RouteLocatorBuilder.Builder routes = builder.routes();        routes.route("path_route_eiletxIE2",r -> r.path("/guoji")                        .uri("http://news.baIDu.com/guoji")).build();        return routes.build();    }}

config

通过服务名实现动态

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

启动:

一个eureka7001+两个服务提供者8001/8002

POM
<dependency>    <groupID>org.springframework.cloud</groupID>     <artifactID≥spring-cloud-starter-netflix-eureka-clIEnt</artifactID></dependency>
YML
server:  port: 9527spring:  application:    name: cloud-gateway  cloud:    gateway:      discovery:        locator:          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由      routes:        - ID: payment_route # 路由的ID,建议配合服务名          #匹配后提供服务的路由地址          #uri: http://localhost:8001          uri: lb://cloud-payment-service          predicates:            - Path=/payment/get/** # 断言,路径相匹配的进行路由        - ID: payment_route2          #uri: http://localhost:8001          uri: lb://cloud-payment-service          predicates:            Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:  instance:    hostname: cloud-gateway-service  clIEnt:    fetch-registry: true    register-with-eureka: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka/

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

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

测试

http://localhost:9527/payment/lb
8001/8002两个端口切换

Predicate是什么

启动我们的gateway9527

Route Predicate FactorIEs这个是什么东东


Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapPing基础架构的一部分。
Spring Cloud Gateway包括许多内置的Route PredicateI厂。所有这些Predicate都与http请求的不同属性匹配。 多个Route Predicate工厂可以进行组合

Spring Cloud Gateway创建Route对象时,使用 RoutePredicateFactory创建Predicate 对象,Predicate 对象可以赋值给Route。Spring Cloud Gateway包含许多内置的Route Predicate FactorIEs.

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

常用的Route Predicate

1.After Route Predicate


@H_793_403@2.Before Route Predicate3.Between Route Predicate4.cookie Route Predicate

不带cookies访问

带上cookies访问

加入curl返回中文乱码
https://blog.csdn.net/leedee/article/details/82685636

5.header Route Predicate


6.Host Route Predicate

7.Method Route Predicate

8.Path Route Predicate9.query Route Predicate

YML


10.RemoteAddr Route Predicate11.Weight Route Predicate小总结

ALL

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

Filter的使用是什么Spring Cloud Gateway的filter生命周期,Only Twoprepost种类,Only TwoGatewayFilter

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/HTML/#gatewayfilter-factorIEs

GlobalFilter

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

常用的GatewayFilterAddRequestParameter

YML

省略自定义过滤器自定义全局GlobalFilter两个主要接口介绍

implments GlobalFilter,OrderID

能干嘛全局日志记录统一网关鉴权.....案例代码
package com.atguigu.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.http.server.reactive.ServerhttpRequest;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Date;/** * 全局自定义过滤器 * * @author zzyy * @version 1.0 * @create 2020/03/06 */@Component@Slf4jpublic class MyLogGatewayFilter implements GlobalFilter,Ordered {    @OverrIDe    public Mono<VoID> filter(ServerWebExchange exchange,GatewayFilterChain chain) {        log.info("come in global filter: {}",new Date());        ServerhttpRequest request = exchange.getRequest();        String uname = request.getqueryParams().getFirst("uname");        if (uname == null) {            log.info("用户名为null,非法用户");            exchange.getResponse().setStatusCode(httpStatus.NOT_ACCEPtable);            return exchange.getResponse().setComplete();        }        // 放行        return chain.filter(exchange);    }    /**     * 过滤器加载的顺序 越小,优先级别越高     *     * @return     */    @OverrIDe    public int getorder() {        return 0;    }}
测试启动

正确:http://localhost:9527/payment/lb?uname=z3错误:http://localhost:9527/payment/lb 总结

以上是内存溢出为你收集整理的【SpringCloud】Gateway新一代网关全部内容,希望文章能够帮你解决【SpringCloud】Gateway新一代网关所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1215423.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存