SpringCloud H版 GateWay 网关路由讲解
Posted 小毕超
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud H版 GateWay 网关路由讲解相关的知识,希望对你有一定的参考价值。
一、GateWay 网关
在上篇文章中我们介绍了,hystrix 的使用,本篇文章我们继续探索,Spring cloud GateWay网关:
上篇文章地址:https://blog.csdn.net/qq_43692950/article/details/121998205
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等。
Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
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 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
为什么选择GateWay呢?
一方面因为Zuul1.0已经进入了维护阶段,而且Gateway是SpringCloud团队研发的,是亲儿子产品,值得信赖。而且很多功能Zuul都没有用起来也非常的简单便捷。
Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的 Zuul 2.x,但 Spring Cloud 貌似没有整合计划。而且Netflix相关组件都宣布进入维护期;不知前景如何?
多方面综合考虑Gateway是很理想的网关选择。
Spring Cloud Gateway 具有如下特性:
- 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
- 动态路由:能够匹配任何请求属性;
- 可以对路由指定 Predicate(断言)和 Filter(过滤器);
- 集成Hystrix的断路器功能;
- 集成 Spring Cloud 服务发现功能;
- 易于编写的 Predicate(断言)和 Filter(过滤器);
- 请求限流功能;
- 支持路径重写。
GateWay 对比 Zuul
在SpringCloud Finchley 正式版之前,Spring Cloud 推荐的网关是 Netflix 提供的Zuul,但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 的性能相对较差。
Netflix 官方早就称开发zuul2,并且适配现在大数据的是时代,但随着Spring Cloud Gateway的出现及使用的普遍性,zuul2也不怎么被人提起。下面是两者的优点介绍:
-
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 Boot 2 之上, 使用非阻塞 API。
-
Spring Cloud Gateway 还 支持 WebSocket, 并且与Spring紧密集成拥有更好的开发体验
二、准备服务提供者
由于我们还没讲解到nacos,本篇文章我们还是使用注册中心eureka,还是接着前几篇的搭建的架构继续,启动注册中心,还有服务提供者:
由于今天主要讲解GateWay,大家也可以改写为自己的接口。
以下是提供者所提供的接口。
@RestController
public class ProviderController
@Value("$server.port")
private String port;
@GetMapping("/getData")
public ResponseTemplate providerData()
return ResSuccessTemplate.builder().data("come from : " + port).build();
@GetMapping("/provider/getData")
public ResponseTemplate providerData2()
return ResSuccessTemplate.builder().data("providerData2 come from : " + port).build();
@GetMapping("/getTimeData")
public ResponseTemplate getTimeData() throws InterruptedException
TimeUnit.SECONDS.sleep(5);
return ResSuccessTemplate.builder().data("come from : " + port).build();
三、搭建GateWay 网关
本篇还是采用Spring cloud H版 S9 版本进行演示:
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<model.version>0.0.1-SNAPSHOT</model.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>$spring-boot.version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>$spring-cloud.version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
新建SpringBoot项目,在pom中引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
注意这里不要引入spring-boot-starter-web
这个包,Spring cloud gateway 使用的webflux,引入web包会报错,提示你不要引用。
主启动类:
@SpringBootApplication
@EnableEurekaClient
public class GateWayApplication
public static void main(String[] args)
SpringApplication.run(GateWayApplication.class, args);
修改配制文件:
server:
port: 80
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://eureka1:8010/eureka,http://eureka2:8011/eureka
spring:
application:
name: gateway
cloud:
gateway:
httpclient:
connect-timeout: 2000
response-timeout: 10s
routes:
- id: provider1
uri: http://127.0.0.1:8091
order: 0
predicates:
- Path=/provider1/**
filters:
- StripPrefix=1 # 去除请求地址中的前缀
上面配制文件eureka的配制就不多说了,主要看下面 gateway的配制,- id 表示声明一个路由规则,保证唯一即可,uri 表示代理后的地址,order 排序,如果有多个规则们可以使用这个指定顺序,predicates 这个是本篇文章的重点,表示断言,也就是路由规则,上面配制的规则就是请求地址中以 /provider1 开头的地址会转发到 uri 中,最后是指定了一个 过滤器,这个 StripPrefix=1 表示去除请求地址中的前缀,如果不加这个过滤器,转发的地址就是 http://127.0.0.1:8091/provider1/
路由规则一方面可以在配制中声明出来,也可以在程序中声明出来,比如:
@Configuration
public class GateWayConfig
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder)
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("provider1",
r -> r.path("/provider1")
.uri("http://127.0.0.1:8091")).build();
return routes.build();
现在大多还是以配制文件中配制为主,本篇文章也已配制文件为主讲解。
下面浏览器请求:http://127.0.0.1/provider1/getData
到此就已经有网关转发的功能了,下面学习下,更多转发方面的技能。
四、predicates 断言
上面说到,本篇的主要内容是predicates 断言,基本所有的转发规则都是配制在predicates 中的。
下面是 predicates 所支持的功能。
官方文档: https://docs.spring.io/spring-cloud-gateway/docs/3.0.5-SNAPSHOT/reference/html/
1. 转发注册中心的服务
配制修改:
- id: provider
uri: lb://provider/
predicates:
- Path=/provider/**,/lbprovider/** #或者
filters:
- StripPrefix=1 # 去除请求地址中的前缀
浏览器请求:http://127.0.0.1/lbprovider/getData
可以看出如果多个,默认采用轮训的效果。
2. 过滤 请求头 Header
现在基本都是前后端分离,那用户的状态使用多的应该就是token了,而token我们一般是放在请求头上,因此我们可以过滤,请求头中没有token,不允许访问:
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Header=token
- Path=/provider1/**
filters:
- StripPrefix=1 # 去除请求地址中的前缀
使用postman访问:http://127.0.0.1/provider1/getData
在header中加入token
参数
3. 过滤 请求参数
限制必须携带某些参数:
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Path=/provider1/**
- Query=user
filters:
- StripPrefix=1 # 去除请求地址中的前缀
4. 过滤 请求 ip
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Path=/provider1/**
- RemoteAddr=192.168.1.7
filters:
- StripPrefix=1 # 去除请求地址中的前缀
必须使用 http://192.168.1.7/provider1/getData?user=123
才可以访问:
4. 过滤 请求 Host
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Path=/provider1/**
- Host=eureka1
filters:
- StripPrefix=1 # 去除请求地址中的前缀
必须使用:http://eureka1/provider1/getData?user=123
才能访问
5. 过滤 请求方法
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Path=/provider1/**
- Method=GET
filters:
- StripPrefix=1 # 去除请求地址中的前缀
限制只有Get请求会转发
6. 过滤 cookie
- id: provider1
uri: http://127.0.0.1:8091/provider
order: 0
predicates:
- Path=/provider1/**
- Cookie=sessionId
filters:
- StripPrefix=1 # 去除请求地址中的前缀
限制只有Cookie中带有 sessionId 参数的可以转发。
7. 请求添加前缀
- id: provider1
uri: http://127.0.0.1:8091
order: 0
predicates:
- Path=/provider1/**
filters:
- StripPrefix=1 # 去除请求地址中的前缀
- PrefixPath=/provider #添加前缀
喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!
以上是关于SpringCloud H版 GateWay 网关路由讲解的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud H版 GateWay 过滤器讲解 及 使用Guava 统一限流处理。
SpringCloud(Greenwich版)新一代API网关Gateway
3W字吃透:微服务网关SpringCloud gateway底层原理和实操