springcloud-路由gateway-zuul
spring-cloud-Gateway
是spring-cloud
的一个子项目。而zuul
则是netflix
公司的项目,只是spring将zuul
集成在spring-cloud中使用而已。
因为zuul2.0
连续跳票和zuul1
的性能表现不是很理想,所以催生了spring团队开发了Gateway
项目。
Zuul:
使用的是阻塞式的 API,不支持长连接,比如 websockets。
底层是servlet,Zuul处理的是http请求
没有提供异步支持,流控等均由hystrix支持。
依赖包spring-cloud-starter-netflix-zuul。
Gateway:
Spring Boot和Spring Webflux提供的Netty底层环境,不能和传统的Servlet容器一起使用,也不能打包成一个WAR包。
依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter。
二、相同点:
1、底层都是servlet
2、两者均是web网关,处理的是http请求
三、不同点:
1、内部实现:
gateway对比zuul多依赖了spring-webflux,在spring的支持下,功能更强大,内部实现了限流、负载均衡等,扩展性也更强,但同时也限制了仅适合于Spring Cloud套件
zuul则可以扩展至其他微服务框架中,其内部没有实现限流、负载均衡等。
2、是否支持异步
zuul仅支持同步
gateway支持异步。理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定
3、框架设计的角度
gateway具有更好的扩展性,并且其已经发布了2.0.0的RELESE版本,稳定性也是非常好的
4、性能
WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。使用非阻塞API。 Websockets得到支持,并且由于它与Spring紧密集成,所以将会是一个更好的 开发 体验。
Zuul 1.x,是一个基于阻塞io的API Gateway。Zuul已经发布了Zuul 2.x,基于Netty,也是非阻塞的,支持长连接,但Spring Cloud暂时还没有整合计划。
四、总结
总的来说,在微服务架构,如果使用了Spring Cloud生态的基础组件,则Spring Cloud Gateway相比而言更加具备优势,单从流式编程+支持异步上就足以让开发者选择它了。
对于小型微服务架构或是复杂架构(不仅包括微服务应用还有其他非Spring Cloud服务节点),zuul也是一个不错的选择。
Spring WebFlux是随Spring 5推出的响应式Web框架。
1、spring-webflux支持两种开发模式:
(1)类似于Spring WebMVC的基于注解(@Controller、@RequestMapping)的开发模式;
(2)Java 8 lambda风格的函数式开发模式。
2、WebFlux是基于响应式流的,可以用来建立异步、非阻塞、事件驱动的服务。默认采用Reactor作为响应式流的实现库,也提供对RxJava的支持。
微服务网关Zuul和Gateway的区别
Zuul:
使用的是阻塞式的 API,不支持长连接,比如 websockets。
底层是servlet,Zuul处理的是http请求
没有提供异步支持,流控等均由hystrix支持。
依赖包spring-cloud-starter-netflix-zuul。
Gateway:
Spring Boot和Spring Webflux提供的Netty底层环境,不能和传统的Servlet容器一起使用,也不能打包成一个WAR包。
依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter。
二、相同点:
1、底层都是servlet
2、两者均是web网关,处理的是http请求
三、不同点:
1、内部实现:
gateway对比zuul多依赖了spring-webflux,在spring的支持下,功能更强大,内部实现了限流、负载均衡等,扩展性也更强,但同时也限制了仅适合于Spring Cloud套件
zuul则可以扩展至其他微服务框架中,其内部没有实现限流、负载均衡等。
2、是否支持异步
zuul仅支持同步
gateway支持异步。理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定
3、框架设计的角度
gateway具有更好的扩展性,并且其已经发布了2.0.0的RELESE版本,稳定性也是非常好的
4、性能
WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。使用非阻塞API。 Websockets得到支持,并且由于它与Spring紧密集成,所以将会是一个更好的 开发 体验。
Zuul 1.x,是一个基于阻塞io的API Gateway。Zuul已经发布了Zuul 2.x,基于Netty,也是非阻塞的,支持长连接,但Spring Cloud暂时还没有整合计划。
Spring WebFlux是随Spring 5推出的响应式Web框架。
1、spring-webflux支持两种开发模式:
(1)类似于Spring WebMVC的基于注解(@Controller、@RequestMapping)的开发模式;
(2)Java 8 lambda风格的函数式开发模式。
2、WebFlux是基于响应式流的,可以用来建立异步、非阻塞、事件驱动的服务。默认采用Reactor作为响应式流的实现库,也提供对RxJava的支持
springcloud gateway 与zuul1.x
一、zuul1.x
二、gateway
基于异步非阻塞进行开发
1)动态路由:能够匹配任何请求属性
2)可以对路由指定Predicate(断言)和Filter(过滤器);
3) 集成Hystrix的断路器功能
4)请求限流;支持路径重写
三、区别
1、Zuul1.x,基于阻塞I/O的api Gateway
2、Zuul1.x基于Servlet2.5使用非阻塞架构它不支持长连接(如WebSocket)Zuul的设计模式和Nginx较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx 用C++实现,Zuul用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul的性能相对较差
3、Zuul2.x理念更先进,想基于Netty 非阻塞和支持长连接,但SpringCloud 目前还没有整合.Zuul2.x的性能较Zuul1.x有较大提升在性能方面,根据官方提供的基准测试,Spring Cloud Gateway 的RPS(每秒请求数)是Zuul的1.6倍
4、Spring Cloud Gateway 建立在Spring Framework 5、Project Reactor 和Spring Boot 2之上,使用非阻塞Apl
5、Spring Cloud Gateway i 还支持WebSocket ,并且与Spring 紧密集成拥有更好的开发体验
-----------------
Zuul:
1. 场景描述
今天接着介绍springcloud,今天介绍下springcloud的路由网关-Zuul,外围系统或者用户通过网关访问服务,网关通过注册中心找到对应提供服务的客户端,网关也需要到注册中心进行注册。
2. 解决方案
2.1 官网架构图
先把官网的图在贴一下,便于理解。
说明: gateway负责与外部进行交互,是sprincloud微服务对外的窗口。
2.2 开始撸码
2.2.1 new—>project
2.2.2 选择组件
(1)注册客户端
(2)路由Zuul
next->next ->finish完成创建
2.2.3 代码介绍
说明:Zuul其实也是注册中心的客户端,主要也是3个类或文件。
(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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spc</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
说明:
springboot两个starter:client与Zuul。
(2)application启动类
package com.spc.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
说明:
启动类主要三个标签:@SpringBootApplication、@EnableEurekaClient、@EnableZuulProxy。
(3)application.yml
spring:
application:
name: gateway
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 9000
说明:
主要就一个地址:http://localhost:8761/eureka/,这个是注册中心地址。
2.2.4 路由访问
(1)启动注册中心、客户端、路由Zuul
(2)通过路由访问client客户端服务
路由地址:http://localhost:9000/client
访问格式:路由地址+客户端服务注册名称,对应上面的application。
getway和zuul在zuul没有进行参数调优的时候,getway的性能会远高于zuul。
分析,在空负载的时候,SpringCloud Gateway比zuul 1 性能高50%左右,在模拟处理50ms业务后,,SpringCloud Gateway比zuul 1 性能高9倍左右。
但是考虑到zuul使用默认配置,结果可能不准,上网查找zuul生产优化配置调优后再次进行50ms业务处理压测。而SpringCloud Gateway查阅资料后暂无需优化。
zuul优化参数参考如下:
性能比较结论
在实际生产使用中zuul 1与gateway性能没有差距:
在实际生产使用中,zuul 1虽然使用的是同步io,但是可以通过参数优化提高性能理论上可以达到极限性能,而springcloud gateway使用的是异步io,不需优化既可以达到接近极限的性能。
zuul1与gateway选择参考
如果是新的spring cloud项目,还是使用getway ,spring的官方都在主推getway,然而 zuul目前只支持到1.3.1版本,后来zuul升级版zuul2,然而zuul2它也是使用异步的netty,getway更加兼容如springcloud;
-----------------
SpringCloud Gateway 简介
springcloud getway 它是基于spring 5.0 、spring boot 2.0 和spring reacter,为微服务提供一个简单有效的网关API路由接口。
Spring Cloud GetWay 作为Spring Cloud生态系统的网关,目标是为了代替zuul,SpringCloud GetWay 是基于webFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
spring cloud getway的目标,提供统一的路由方式,基于Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
Spring Cloud Gateway 底层使用了高性能的通信框架Netty。
Gateway 由三部分组成:
(1)Filter(过滤器):
使用它拦截和修改请求,并且对上游的响应,进行二次处理。
(2)Route(路由):
一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
(3)Predicate(断言):
这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。
Gateway:
1. 场景描述
springcloud刚推出的时候用的是netflix全家桶,路由用的zuul(springcloud-路由Zull),但是据说zull1.0在大数据量访问的时候存在较大性能问题,2.0就没集成到springcloud中了,springcloud推出了自己的路由-springcloud gateway,亲儿子,目前官网主推。
netfelix的zull路由:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2. 解决方案
2.1 新建springboot项目
在springcloud项目中,新建的项目全部是基于springboot的(springboot与springcloud的关系),新建springboot项目再啰嗦一遍吧(springboot项目快速搭建)
2.1.1 new->project
next->next 更改下项目名称。
2.1.2 选择组件
(1)注册中心客户端
(2) 选择springcloud gateway
next->next, 完成。
2.2 类目录图
开始介绍springcloud-gateway,为了区分上一篇的关于zull的介绍,项目名称设置为springgate。
2.3 重点还是三个文件
2.3.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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yutong</groupId>
<artifactId>springgateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springgateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
说明,重点就两个starter:
(1)gateway,不同于zull,这个是直接位于spring-cloud下面,是springcloud的嫡系部队。
(2)注册中心客户端,不多说了
2.3.2 启动类application
package com.yutong.springgateway;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringgatewayApplication {
@Value("${test.uri}")
private String uri;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
//basic proxy
.route(r -> r.path("/**")
.uri(uri)
).build();
}
public static void main(String[] args) {
SpringApplication.run(SpringgatewayApplication.class, args);
}
}
说明:
(1)不同于路由zull,需要zull的标签,这里只需要springboot的启动标签@SpringBootApplication就可以了。
(2)增加@Bean标签,RouteLocator 是路由规则,这个稍微复杂点,示例中只做了简单配置,路由规则用于过滤控制路由等,可根据具体需求,参考路由规则API进行设置。
2.3.3 配置类application.yml
test:
uri: lb://client
spring:
application:
name: springgateway
cloud:
gateway:
discovery:
locator:
lower-case-service-id: true
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
server:
port: 9000
说明:
(1)第一行的uri在启动类application中用到,指访问的客户端服务,client为注册中心客户端服务名称。
(2)defaultZone为注册中心地址。
(3) 为了区分介绍zull的项目,name设置为:springgateway
2.3.4 效果图
(1)注册中心
(2)路由springcloud gateway访问
说明:
路由访问的时候不需要指定客户端名称client,因为在gateway启动类中已经指定过了。
-----------------