概述
-
zuul官网:2.0还没出来
-
gateway官网:spring等不及自己研发的
-
gateway是原zuul1.x的替代
-
Gateway是Spring生态系统之上构建的API网关服务,基于Spring5,Spring Boot2和Project Reactor等技术
-
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤功能,例如:熔断,限流,重试等。
-
SpringCloud Gateway作为Spring Cloud生态系统中的网关,目的是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul2.0以上最新高性能版本进行集成,仍然还是使用Zuul1.x非Reactor模式的老版本。而为了提升网关性能,SpringCloud GateWay是基于WebFlux框架实现的,而WebFlux框架底层则使用高性能的Reactor模式通信框架Netty。
SpringCloud Gateway 使用的WebFlux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
微服务架构中网关的作用和位置
- 反向代理
- 鉴权
- 流量监控
- 熔断
- 日志监控
Spring Cloud GateWay特性
- 基于SpringFrame 5,Project Reactor和Spring Boot2.0进行构建
- 动态路由:能够匹配任何请求属性
- 可以对路由指定Predicate(断言)和Filter(过滤器)
- 集成Hystrix的断路器功能
- 集成Spring Cloud服务发现功能
- 易于编写的Predicate(断言)和Filter(过滤器)
- 请求限流功能
- 支持路径重写
Spring Cloud Gateway 与Zuul的区别
在SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix提供的Zuul:
- Zuul1.x是一个基于阻塞I/O的APIGateway
- Zuul1.x基于Servlet2.5使用阻塞架构,它不支持任何长连接(如websocket)Zuul的涉及模式和Nginx较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用Java实现,而JVM本身会又第一次加载较慢的情况,所以Zuul的性能相对较差。
- Zuul2.x理念更先进,想基于Netty非阻塞和支持长连接,但是Spring Cloud目前还没有整合
- Spring Cloud Gateway建立在Spring Framework5,Project Reactor和Spring boot2之上,使用非阻塞API。
- Spring Cloud Gateway支持WebSocket,并且与Spring紧密集成拥有更好的开发体验。
webflux
- 传统的Web框架,如springmvc基于Servlet API与Servlet容器基础之上运行的,Servlet3.1之后有了异步非阻塞的支持,而WebFlux是一个点典型非阻塞异步的框架,它的核心是基于Reacotr的相关API实现的,相对于传统的web框架来说,它可以运行诸如Netty,Undertow及支持Servlet3.1的容器上。非阻塞式+函数式编程
- WebFlux是Spring5.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中找到与请求相匹配的路由,将其发送到GatewayWebHandler
- Hadler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回
- 过滤器之间用虚线分开是因为过滤器可能会再发送代理请求之前(pre)或之后(post)执行业务逻辑
- Filter再pre类型的过滤器可以做参数校验,权限校验,流量监控,日志输出,协议转换等
- 再post类型的过滤器中还可以做响应内容,响应头的修改,日志的输出,流量监控等
入门案例
建module
编pom
<dependencies>
<!-- gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.hsw.cloud</groupId>
<artifactId>cloud-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>
写yml
主启动
需求,如何做路由映射
- cloud-provider-payment8001看看controller的访问地址有get访问和lb访问
- 我们目前不想暴露8001端口,希望在8001外面套一层9527
添加配置
显示实际端口是8001
Gateway网关路由有两种配置方式:
- 配置文件yml中配置,如上所示
- 代码中注入RouteLocator的Bean
- 自己实现一个访问9527,跳到百度页面
/guonei,映射百度新闻的国内
通过服务名实现动态路由
- 默认情况下Gatway会根据注册中心注册的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
yml配置注意下
 {
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;
}
}
- 此时访问localhost:9527/payment/lb
- 如果带uname