Spring Cloud Gateway真的有那么差吗?
Spring Cloud从一开始最受大家质疑的就是网关性能,那是由于Spring Cloud最初选择了使用Netflix几年前开源的Zuul作为基础,而高性能版的Zuul 2在经过了多次跳票之后,对于Spring这样的整合专家可能也不愿意再继续等待,Spring Cloud Gateway应运而生,那么这个由Spring社区自己开发推出的网关又如何呢?最近一篇《实测 | 转型微服务,这4大工具谁是API网关性能最优?》的翻译中对比了NGINX、ZUUL、Spring Cloud Gateway、Linkerd,得出的结论让不少读者感到诧异,Spring Cloud Gateway是否真的有这么差?不妨通过下文来进一步了解(以下内容转载自来《Spring Cloud与Docker微服务实战》作者周立的博文,原文地址:http://www.itmuch.com/spring-cloud-sum/performance-zuul-and-gateway-linkerd/)。
动机
已经不止一次看到“Spring Cloud Gateway性能比Zuul更差”的言论了,不少人人云亦云,来问我,既然如此,那Spring官方还开发Spring Cloud Gateway干嘛?难道仅仅是为了支持Zuul 1.x不支持的长连接、Web Socket吗?
故而写篇博客,纠正一下大家的错误观点。
开端
网上搜索了一下,说Spring Cloud Gateway性能比Zuul差的言论来自:http://www.servicemesh.cn/?/article/45
作者使用 ab
进行benchmark,操作非常标准。从结果来看,确实Spring Cloud Gateway比Zuul差了一大截。
但,让我们打开官方的Issue:Throughput problems when compared with Netflix Zuul and Nginx ,里面官方人员回答道:
reactor-netty has issues with http 1.0 and hence ab. reactor/reactor-netty#21
不妨跟踪到reactor/reactor-netty#21 ,看看说了啥:
As discussed recently about the issue raised on https://jira.spring.io/browse/SPR-14964, a very simple
ab-n1-c1http://localhost:8082/items/10
on Spring + Reactor Netty based server block forever likely because Reactor Netty does not support HTTP 1.0.
里面说了,Reactor Netty不支持HTTP 1.0,而Spring Cloud Gateway依赖了 reactor-netty
。
也就是说——由于reactor-netty的bug,使用 ab
压测结果并不准确!
正确姿势
官方建议使用 wrk
进行benchmark测试。不仅如此,官方人员还十(丧)分(心)贴(病)心(狂)地创建了一个benchmark的项目:spring-cloud-gateway-bench ,其中对比了:
- Spring Cloud Gateway
- Zuul
- Linkerd
三者的性能。
思路非常简单:static 项目是一个使用Go语言编写的简单服务器;然后分别使用Gateway/Zuul/Linkerd来代理该服务的端点,并对比。
最终结果:
组件 |
RPS(request per second) |
---|---|
Spring Cloud Gateway |
Requests/sec: 32213.38 |
Zuul |
Requests/sec: 20800.13 |
Linkerd |
Requests/sec: 28050.76 |
从结果可知,Spring Cloud Gateway的RPS是Zuul1的1.6倍!比Linkerd性能还好!
展望
- 本文的Zuul,指的是Zuul 1.x,是一个基于阻塞io的API Gateway。
- Spring Cloud Gateway是一个很有前途的项目,上手简单,功能也比较强大。
- Linkerd也是一个非常有前途的项目,是基于Scala实现的、目前市面上仅有的生产级别的Service Mesh(其他诸如Istio、Conduit暂时还不能用于生产)。
- Zuul已经发布了Zuul 2.x,基于Netty,也是非阻塞的,支持长连接,但Spring Cloud暂时还没有整合计划。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- (二)Mybatis-Plus的安装配置
- 如何在JSP里自定义标签
- 如何在JSP里使用Java bean
- 获取指定时间内指定星期几的所有日期
- 使用JSP的标准标签库JSTL处理XML格式的数据
- (一)初识Mybatis-Plus
- org.apache.tomcat.util.scan.StandardJarScanner找不到serializer.jar的问题
- JAVA中获取当前系统时间
- 使用Supervisor管理进程
- vue 中使用threejs
- 数据库COUNT(*)、COUNT(字段)和COUNT(1)的异同
- 生成项目目录树
- 几行代码搞定智能插座控制丨云开发 × 涂鸦
- Elasticsearch Mapping是啥?
- 求水仙花数面试题 撸它