【Hoxton.SR1版本】Spring Cloud 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能干嘛?
- 反向代理
- 鉴权
- 熔断
- 流量控制
- 日志监控
- ...........
- Gateway的特性?
- 基于Spring 5,Spring Boot 2和Project Reactor进行构建;
- 动态路由:能够匹配任何请求属性;
- 可以对路由指定Predicate(断言)和Filter(过滤器);
- 集成Hystrix的断路器功能;
- 集成Spring Cloud服务发现功能;
- 易于编写的Predicate(断言)和Filter(过滤器);
- 请求限流功能;
- 支持路径重写;
- Spring Cloud Gateway和Zuul的区别?
- zuul 1.x是一个基于阻塞I/O的API Gateway;
- zuul 1.x基于Servlet 2.5使用阻塞框架,它不支持任何长连接(如WebSocket),Zuul的设计模式和Nginx较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别就是Nginx用C++实现,Zuul是用Java实现,而JVM本身会有第一次加载比较慢的情况,使得Zuul的性能相对较差;
- Zuul 2.x版本理念更先进,想基于Netty非阻塞和支持长连接,但Spring Cloud目前还没有整合,Zuul 2.x的性能较1.x有较大提升。在性能方面,根据官方提供的基准测试,Spring Cloud Gateway的RPS(每秒请求数量)是Zuul的1.6倍。
- Spring Cloud Gateway建立在Spring 5,Spring Boot 2和Project Reactor之上,使用非阻塞API;
- 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 模块移除,否则启动会报错】
<?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.wsh.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-apigateway-gateway9527</artifactId><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>com.wsh.springcloud</groupId><artifactId>springcloud-api-commons</artifactId><version>${project.version}</version></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></project>
【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中
<!--eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
【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,由于笔者水平有限,如有不对之处,还请小伙伴们指正,相互学习,一起进步。
【Hoxton.SR1版本】Spring Cloud Gateway网关初体验相关推荐
- Spring Cloud Gateway网关
Spring Cloud Gateway网关 1. 简介 Spring Cloud Gateway是Spring官网基于Spring 5.0. Spring Boot 2.0.Project Reac ...
- Spring Cloud Gateway网关实现短网址生成、解析、转发
Spring Cloud Gateway网关实现短网址生成.解析.转发 1.概述 2.基础实现 3.路由处理HandlerFunction 4.配置路由 5.测试 1.概述 在一些生成二维码等场景中, ...
- 网关 翻译版本 spring cloud gateway
Spring Cloud Gateway 官网原文地址 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html ...
- spring cloud gateway网关和链路监控
文章目录 目录 文章目录 前言 一.网关 1.1 gateway介绍 1.2 如何使用gateway 1.3 网关优化 1.4自定义断言和过滤器 1.4.1 自定义断言 二.Sleuth--链路追踪 ...
- 从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析
API 网关 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题 ...
- spring cloud gateway 网关_微服务网关Spring Cloud Gateway全搞定
一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...
- Spring Cloud Gateway — 网关基本功能API暴露
API网关 API网关是一种设计模式,一种在微服务体系下的经典构件.要了解最新API网关模式可以参考敖小剑写的<Service Mesh和Api Gateway关系深度探讨> 早期SOA阶 ...
- 【硬核】Spring Cloud Gateway(网关)
概念 Gateway是基于异步非阻塞模型上进行开发的,有springcloud团队开发.用来代替Zuul. 近几个月收集了收集了N份精校过的PDF版的Java八股文大全,涉及Java后端的方方面面,分 ...
- Spring Cloud Gateway 网关整合 Knife4j
文章目录 1:环境准备 2:gateway服务设置 1:导包 2:yml配置 3:添加配置类,从网关服务中获取服务列表 4:重写并覆盖/swagger-resources接口 3:其他业务逻辑服务设置 ...
- Spring Cloud Gateway网关实战
文章目录 介绍 基础示例 spring-cloud-gateway-service spring-cloud-gateway-sample网关 介绍 Spring Cloud Gateway是Spri ...
最新文章
- Oracle CEO狂妄而真实的演讲
- Android自定义sleep图,android自定义view实现钟表效果
- 为没有源码的DLL文件添加强名称
- C语言实现自组织映射kohone/trace算法(附完整源码)
- 关于Java中的String类
- 如何使Xcode占用更少的空间 Xcode占用空间太大解决方法
- jQuery起点教程之有序化插件实例
- 百度MP3音乐API接口及应用
- c#读取生成excel表格文件xls、xlsx格式文件
- 嫌学校 App烂,极客父母做了开源版本
- 方维出现 Fatal error: Class 'Session' not found
- 基本 SQL 之增删改查
- 想回味Windows95?模拟器+浏览器搞定
- sqlalchemy的基本操作大全
- FEC【筷云早报】 2020年7月29日星期三
- 股票投资 - 如何看懂集合竞价
- 霓虹国推出“肌肉”机器人,疑似现实版“终结者”
- 相控阵雷达天线与MIMO天线的区别
- 微软状告西雅图点击欺诈人,将对那些不法行为产生警示作用
- 共享电动汽车分时租赁TBOX,车联网OBD终端,语音4GTBOX