最近公司要引入统一网关,自己也参与调研了几种,当在研究Netflix的Zuul2和SpringCloudGateway时被网络上杂七杂八的材料跟震惊了,不客气地说很多国内博客都是在误人子弟,充斥着那些基于SpringCloud全家桶号称自己使用的是zuul2的“专家”。所以下定决心用一个系列好好介绍下第二代NIO的两个网关:SpringCloudGateway和NetflixZuul2。

背景介绍

我们系统架构面临现状和痛点

    1.  流量调度不灵活,完全依赖DNS

虽然后端服务已经实现了多云多活,但是每次做流量割接的时候都要从DNS层一个运营商一个运营商的一点点的做调度。我需要有个统一接入层,可以直接把一个云平台的所有流量直接调到另一个云平台上

    2.  各IDC的LB组件不同,配置管理不统一

对接入层的配置,变成了对每个产品LB入口的配置,我们大约有近百个应用,而且每个应用又涉及到物理机房IDC、阿里云、腾讯云这样的差异性,而且每家云平台LB的设计和操作又千差万别,所以接入层的配置变成了臃肿而且学习成本很高的一件事情。

    3.  突发流量导致雪崩,无限流

公司目前没有限流策略,今年春节后因为疫情原因大家都窝在家里,我们的爆款节目就引发了两次因流量洪峰导致的重大故障。虽然后端的服务已经具备了很出色的弹性能力,但是弹性毕竟需要时间,因为缺乏接入层限流的保护,很容易造成后端服务雪崩效应。

    4.  无法干预路由策略,无法混沌工程

今年我们将会启动混沌工程,更需要一个优秀的网关来配合打标或自定义路由,而且要能很好地控制网关的生命周期,因为混沌工程执行是临时性的,混沌结束后需要恢复。

我期望中的统一网关应该具备的能力

1、七层转发:基于path、host、uid、其他自定义方式。

2、拦截策略:统一安全,request、response报文干预。

3、统一管理:统一的监控、日志、配置管理方案。

4、限流熔断:基于不同粒度的限流规则。

现状图

Spring Cloud Gateway VS Netflix Zuul2

理想图

Spring Cloud Gateway VS Netflix Zuul2

网关发展史

选择网关之前我们要先了解下netflix与spring的恩怨情仇

Spring Cloud Gateway VS Netflix Zuul2 

蜜月期

2013: Netflix推出以zuul1为代表开的源项目

2014: SpringBoot诞生,引入Netflix开源组件

2015: SpringCloud诞生,引入Netflix开源组件

2016: 发现Zuul1存在性能问题,Netflix官宣进行优化

争执期

2016-2017: Netflix跳票

2018-05: Netflix发布Zuul 2.x,Spring未引入

2018-06: Netflix宣告Eureka 2.0 开源工作停止

分手

2018-11: Netflix宣告Hystrix开源工作停止

2018-11: Spring推出新一代网关Gateway、一些列孵化项目

2018-12:Spring官方宣布Netflix的相关项目进入维护模式

2018-12::Netflix 宣布 Spring 系列技术栈进入维护模式

SpringCloud因分手受影响的模块

spring-cloud-netflix-archaius

spring-cloud-netflix-hystrix-contract

spring-cloud-netflix-hystrix-dashboard

spring-cloud-netflix-hystrix-stream

spring-cloud-netflix-hystrix

spring-cloud-netflix-ribbon

spring-cloud-netflix-turbine-stream

spring-cloud-netflix-turbine

spring-cloud-netflix-zuul

总之一句话:爱过

网关的发展经历了BIO和NIO时代

一代网关:BIO

实现方式

  基于Thread方式,当I/O阻塞系统,但CPU空闲的时候,可以利用多线程使用CPU资源

性能

  严重依赖于线程,线程的创建和销毁成本很高;

线程本身占用较大内存。

代表

  SpringCloudZuul(Netflix-Zuul1)

Spring Cloud Gateway VS Netflix Zuul2

二代网关:NIO

实现方式

  基于Reactor方式,成熟框架(Netty、MINA),当I/O阻塞系统,但CPU空闲的时候,可以利用多线程使用CPU资源。

性能

  除了事件的轮询是阻塞的,剩余的都是纯CPU操作,单线程处理多任务;

  由于线程的节约,高链接场景下线程切换带来的问题也随之解决;

  I/O多路复用。

代表

  SpringCloudGateway & Netflix-Zuul2

 Spring Cloud Gateway VS Netflix Zuul2

核心网关详解

Zuul2-架构

基于Filter的体系

Inbound

  输入过滤器,在请求被代理之前执行。可用于:认证、路由、Ddos、指标统计等。

Endpoint

  基于输入过滤器的执行情况处理请求,如:将请求代理到后端等。

Outbound

  输出过滤器处理接收到后端服务返回后的操作;如:增删响应头信息、压缩等

Spring Cloud Gateway VS Netflix Zuul2

Zuul2-动态过滤器

核心代码:ZuulFiltersModule,FilterFileManager,FilterLoader

核心配置:zuul.filters.classes,zuul.filters.packages,zuul.filters.locations

Spring Cloud Gateway VS Netflix Zuul2

 

SpringCloudGateway

Gateway Handler Mapping

  找到与请求相匹配的路由,将其发送到 Gateway Web Handler

Gateway Web Handler

  通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑。

Filter

  pre:Gateway转发请求之前

  post:Gateway转发请求之后

Spring Cloud Gateway VS Netflix Zuul2

网关对比与选型

网关对比

 

名称

Zuul1

Zuul2

Spring Cloud Gateway

Path注入

不自带,部分可实现

不自带,可以自己实现

自带

host转发

不支持

不自带,可以自己实现

自带

动态代码

不支持

可动态通过代码修改filter

不支持

动态配置

Archaius,Spring

Netflix Archaius

Spring(config+bus+actuator)或自开发

网关高可用

云平台的LB+弹性,Eureka

云平台的LB+弹性,Eureka

云平台的LB+弹性,Eureka

服务发现

eureka

eureka

eureka,nacos

功能扩展

只扩展过滤器

可创建路由规则,过滤规则

路由规则,过滤规则都可扩展 

限流

信号量、线程数

内置限流统计,需要自己封装实现,集群可能需要自开发

引入redis计数,可细化到针对IP做限流,限流规则可自定义

熔断

Hystrix降级

需要基于内置的统计做封装

利用Hystrix

实现方式

BIO

NIO

NIO

技术选型

性能:

    Gateway和Zuul2底层都是reactor模式,性能上比zuul1时代提高很多,所以zuul1不考虑。

开源:

    Gateway社区更成熟,内置10种路由和20种过滤器,zuul2只有Netflix博客和github可获取相关资料,很多功能需要自己开发。

特性:

    Zuul2基于groovy的filter代码动态更新是一大亮点,而且与混沌工程配合的天衣无缝,从Zuul2的设计思想来看就是要利用代码来替代配置

语言:

    Netflix是Java+Groovy体系,Spring是Java体系

总结: 倾向于Zuul2

 

相关文章: