热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Hoxton.SR1版本】SpringCloudGateway网关初体验

目录一、简介二、Gateway三大概念三、SpringCloudGateway整体流程图四、Gateway入门配置五、Gateway路由配置方式六、Gateway动态路

目录

一、简介

二、Gateway三大概念

三、Spring Cloud Gateway整体流程图

四、Gateway入门配置

五、Gateway路由配置方式

六、Gateway动态路由

七、总结




一、简介

在SpringCloud旧版本中,我们使用的微服务网关是Zuul网关,笔者之前也做了有关Zuul网关的详解,有兴趣的小伙伴可以通过下面的链接进行学习:https://blog.csdn.net/Weixiaohuai/article/details/82717679。在SpringCloud新版本中,新推出了Spring Cloud Gateway新一代网关,它取代了Zuul,所以我们有必要花一点时间去学习Gateway。

Spring Cloud Gateway官网地址为:

https://spring.io/projects/spring-cloud-gateway

https://docs.spring.io/spring-cloud-gateway/docs/2.2.4.RELEASE/reference/html/


  • Spring Cloud Gateway是什么?

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

SpringCloud Gateway项目提供了一个在Spring生态系统之上构建的API网关,包括:Spring 5,Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,例如:安全性,监视/指标和限流。

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


  • Gateway能干嘛?

  1. 反向代理
  2. 鉴权
  3. 熔断
  4. 流量控制
  5. 日志监控
  6. ...........

  • Gateway的特性?

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

  • Spring Cloud Gateway和Zuul的区别?

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

二、Gateway三大概念


  • 路由:网关的基本构建块。它由ID,目标URI、断言和过滤器集合定义。如果断言为true,则匹配路由。

  • 断言:输入类型是Spring Framework ServerWebExchange。开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数,如果请求与断言相匹配则进行路由。

  • Filter:指的是使用特定工厂构造的Spring Framework GatewayFilter实例。可以在请求被路由之前或者之后对请求进行修改。


三、Spring Cloud Gateway整体流程图


  • DispatcherHandler:所有请求的调度器,负载请求分发;
  • RoutePredicateHandlerMapping:路由谓语匹配器,用于路由的查找,以及找到路由后返回对应的WebHandler,DispatcherHandler会依次遍历HandlerMapping集合进行处理;
  • FilteringWebHandler : 使用Filter链表处理请求的WebHandler,RoutePredicateHandlerMapping找到路由后返回对应的FilteringWebHandler对请求进行处理,FilteringWebHandler负责组装Filter链表并调用链表处理请求;

客户端向Spring Cloud Gateway发出请求,如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前("pre")和之后("post")运行逻辑。所有“前置”过滤器逻辑均被执行,然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。


四、Gateway入门配置

下面我们新建一个module【springcloud-apigateway-gateway9527】,这里面去集成Gateway新一代网关。

【a】pom.xml,注意添加spring-cloud-starter-gateway依赖

注意:【spring-cloud-starter-gateway不需要spring-cloud-starter-web,需要将 web 模块移除,否则启动会报错】


springcloud2020com.wsh.springcloud1.0-SNAPSHOT4.0.0springcloud-apigateway-gateway9527org.springframework.cloudspring-cloud-starter-gatewayorg.springframework.cloudspring-cloud-starter-netflix-eureka-clientcom.wsh.springcloudspringcloud-api-commons${project.version}org.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

【b】application.yml配置文件:最主要的就是网关URL映射的配置,由上可知,gateway网关三要素: 路由ID、断言Predicate、过滤器(可有可无),所以我们作出如下配置:

server:port: 9527
spring:application:name: springcloud-gatewaycloud:gateway:routes:#如下配置表示,当浏览器URL访问localhost:9527/gatewaySimple/**的时候,gateway网关会帮忙转发到http://localhost:8001/gatewaySimple/**去.- id: payment8001_gatewaySimple #路由的ID,没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8001 #指定payment8001的访问地址,即匹配后提供服务的路由地址predicates:- Path=/gatewaySimple/** # 断言,路径相匹配的进行路由
eureka:instance:hostname: springcloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #集群版Eureka注册中心

如上路由转发配置说明:

当浏览器URL访问 localhost:9527/gatewaySimple/** 的时候,gateway网关会帮忙转发到http://localhost:8001/gatewaySimple/**去。

【c】主启动类

package com.wsh.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class GateWayServiceApplication9527 {public static void main(String[] args) {SpringApplication.run(GateWayServiceApplication9527.class, args);}
}

【d】服务提供方【springcloud-provider-payment8001】增加如下接口,很简单,这里就不过多叙述。

/*** 测试gateway网关转发请求简单示例*/@GetMapping("/gatewaySimple/{name}")public String testGateway(@PathVariable("name") String name) {return "hello, the name is :" + name;}

【e】测试

启动项目,我们首先访问http://localhost:8001/gatewaySimple/weixiaohuai,运行结果如下图:

可见,服务提供方的gatewaySimple接口是通的,下面,我们使用网关地址来访问:http://localhost:9527/gatewaySimple/weixiaohuai

可以看到,gateway成功转发请求。


五、Gateway路由配置方式

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


  • application.yml文件中配置;
  • 代码中注入RouteLocator的bean;

上面我们已经学习了如何在yml配置文件中配置的方法,接下来我们使用第二种方式进行配置。

官网案例:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#configuration

【a】服务提供方增加如下方法

/*** 测试gateway网关转发请求简单示例 - RouteLocator方式*/@GetMapping("/gatewaySimpleRouteLocator/{name}")public String gatewaySimpleRouteLocator(@PathVariable("name") String name) {return "hello, [RouteLocator] the name is :" + name;}

【b】定义RouteLocator的配置类

package com.wsh.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;/*** @version V1.0* @ClassName: com.wsh.springcloud.config.CustomRouteLocatorConfig.java* @Description: 自定义路由定位器配置* @author: weishihuai* @date: 2020/8/19 13:40*/
@Configuration
public class CustomRouteLocatorConfig {@Beanpublic RouteLocator routes(RouteLocatorBuilder routeLocatorBuilder) {RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();routes.route("payment8001_gatewaySimpleRouteLocator", //路由IDr -> r.path("/gatewaySimpleRouteLocator/**") //路由路径正则表达式.uri("http://localhost:8001") //跳转目标服务地址).build();return routes.build();}}

参照application.yml配置文件的方式,如上路由转发配置说明:

当浏览器URL访问 localhost:9527/gatewaySimpleRouteLocator/** 的时候,gateway网关会帮忙转发到http://localhost:8001/gatewaySimpleRouteLocator/**去。

【c】测试 

启动项目,浏览器访问:http://localhost:8001/gatewaySimpleRouteLocator/weixiaohuai

确保服务提供方的接口gatewaySimpleRouteLocator是通的,然后我们使用网关路径去访问:http://localhost:9527/gatewaySimpleRouteLocator/weixiaohuai

可见,网关也成功了完成了路由转发,以上就是用编码的方式实现gateway网关进行路由映射配置的方法。


六、Gateway动态路由

我们注意到,上面访问的路由地址我们是写死的【uri: http://localhost:8001 #指定payment8001的访问地址,即匹配后提供服务的路由地址】,在微服务架构中,微服务提供者不可能是单机部署,如果在集群环境下,如果写死某个服务的话,写死路由那肯定就不行了,所以就需要使用动态路由。


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

下面,我们以一个简单的示例说明如何实现动态路由,需要修改的地方如下:

【a】修改Gateway网关服务的pom.xml,将网关服务注册进Eureka中

org.springframework.cloudspring-cloud-starter-netflix-eureka-client

【b】服务提供方增加如下方法

/*** 测试gateway网关转发负载均衡转发*/@GetMapping("/gatewayLoadBalance/{name}")public String gatewayLoadBalance(@PathVariable("name") String name) {return "hello, [gatewayLoadBalance] the name is :" + name + ", the server port is " + serverPort;}

注意:由于需要测试网关的负载均衡调用,所以两个服务提供者payment8001、8002都需要加上此方法。


【c】修改application.yml,需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。


  • lb://serviceName是springcloud gateway在微服务中自动为我们创建的负载均衡uri。

具体修改的地方:


  • spring.cloud.gateway.discovery.locator.enabled=true   #开启从注册中心动态创建路由的功能,利用微服务名进行路由
  • lb://serviceName负载均衡配置

server:port: 9527
spring:application:name: springcloud-gatewaycloud:gateway:routes:#如下配置表示,当浏览器URL访问localhost:9527/gatewaySimple/**的时候,gateway网关会帮忙转发到http://localhost:8001/gatewaySimple/**去.- id: payment8001_gatewaySimple #路由的ID,没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8001 #指定payment8001的访问地址,即匹配后提供服务的路由地址predicates:- Path=/gatewaySimple/** # 断言,路径相匹配的进行路由#如下配置表示,当浏览器URL访问localhost:9527/gatewayLoadBalance/**的时候,gateway网关负载均衡地将请求分发到springcloud-payment-service服务中去.- id: payment_service_loadbalance #路由IDuri: lb://springcloud-payment-service #springcloud-payment-service为服务提供者注册到Eureka的应用名称(application name)predicates:- Path=/gatewayLoadBalance/** # 断言,路径相匹配的进行路由discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
eureka:instance:hostname: springcloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #集群版Eureka注册中心

 【d】测试

启动两个服务提供者payment8001和payment8002、网关服务9527,查看服务是否都正常注册进Eureka:

,浏览器访问:http://localhost:9527/gatewayLoadBalance/weixiaohuai,访问多几次,观察运行结果:

可见,运行结果请求后端服务的端口号是8001、8002交替出现,网关gateway成功帮我们完成了负载均衡转发请求到【springcloud-payment-service】 的功能,以上就是关于gateway中动态路由的配置方法。


七、总结

本篇文章主要介绍了新一代网关Spring Cloud Gateway的概念,优点以及与Zuul的比较,并简单总结了一下gateway中路由配置的两种方式,还通过一个简答的示例说明了如何配置动态路由,当然gateway的内容远远不止这些,还有一些Predicate断言、Filters过滤器等等,我们在下篇文章进行介绍。

以上相关项目的代码我已经放在Gitee上,有需要的小伙伴可以去拉取进行学习:https://gitee.com/weixiaohuai/springcloud_Hoxton,由于笔者水平有限,如有不对之处,还请小伙伴们指正,相互学习,一起进步。


推荐阅读
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • zuul 路由不生效_Zuul网关到底有何牛逼之处?竟然这么多人在用~
    作者:kosamino来源:cnblogs.comjing99p11696192.html哈喽,各位新来的小伙伴们,大家好& ... [详细]
  • TiDB | TiDB在5A级物流企业核心系统的应用与实践
    TiDB在5A级物流企业核心系统的应用与实践前言一、业务背景科捷物流概况神州金库简介二、现状与挑战神州金库现有技术体系业务挑战应对方案三、TiDB解决方案测试迁移收益问题四、说在最 ... [详细]
  • 后台自动化测试与持续部署实践
    后台自动化测试与持续部署实践https:mp.weixin.qq.comslqwGUCKZM0AvEw_xh-7BDA后台自动化测试与持续部署实践原创 腾讯程序员 腾讯技术工程 2 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 本文介绍了使用数据库管理员用户执行onstat -l命令来监控GBase8s数据库的物理日志和逻辑日志的使用情况,并强调了对已使用的逻辑日志是否及时备份的重要性。同时提供了监控方法和注意事项。 ... [详细]
author-avatar
唤起
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有