在CNCF组织的一场技术分享会上,第一次听到了 Enovy 这么一个货色,分享的嘉宾巴拉巴拉讲了一大堆,啥都没记住,就记住了一个特地新鲜的概念“通信总线”,前面 google 了下 Envoy 这个货色到底是什么,发现官网上如是形容:

“_Envoy 是专为大型古代 SOA(面向服务架构)架构设计的 L7 代理和通信总线_”

也就是说, Envoy 是为了解决 Server Mesh 畛域而诞生一款 L7 代理软件,这里我网上找了一张图,我了解种的 Envoy 大略是如下的部署架构。(如果错了请大佬指教)


既然是L7的代理软件嘛,作为长年混迹 openresty 社区的老司机,天然忍不住把它拿来搞一搞,比照比照。

咱们抉择的比试对象是最近刚从 Apache 社区毕业的 APISIX,它是基于 OpenResty 实现的 API 网关。(其实也就是 L7 代理而后加了路由、认证,限流、动静上游等等之类的性能)

为什么抉择它呢,因为有一次社区分享的时候据说这货的路由实现十分棒,正好咱们的当初业务的路由零碎乌七八糟,扒拉了下 APISIX 的源码,发现的确是6到飞起,吊打我看到过的同类产品, 所以印象粗浅,就它了!

这里附上一张在 APISIX 官网扒拉的图,真是一图胜千言,一看就晓得这玩意儿是怎么工作的;

开搞吧,首先咱们去官网找到两个产品的最版本:

Apache APISIX 1.5 和 Envoy 1.14

构建环境筹备

  • 压力测试客户端:wrk;
  • 测试次要指标包含:网关提早、QPS 和是否线性扩大;
  • 测试环境:微软云 Linux (ubuntu 18.04), Standard D13 v2 (8 vcpus, 56 GiB memory);
  • 测试形式1:采纳单核运行横向比照(因为它们都是基于 epoll 的IO模型,所以用单核压测验证它们的解决能力);
  • 测试形式2:采纳多核运行横向比照,次要是为了验证两者在增加多(过程|线程)的场景下其整体解决能力是否可能线性增长;

测试场景

这里咱们用 nginx 搭建了一个上游服务器,配置 2 个 worker,接管到申请间接应答 4k 内容,参考配置如下:

server {  listen 1980;    access\_log off;  location = /hello {    echo\_duplicate 400 "1234567890";  }}
  • 网络架构示意图如下:(绿色失常负载,未跑满。红色为低压负载,要把过程资源跑满,次要是 CPU)

路由配置

首先咱们找到 APISIX 的入门配置指南,咱们增加一条到 /hello 的路由,配置如下:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '{、    "uri": "/hello",    "upstream": {        "type": "roundrobin",        "nodes": {            "127.0.0.1:1980": 1        }    }}'

须要留神的是,这里没并没有开始 proxy_cache 和 proxy_mirror 插件,因为Enovy并没有相似的性能;

而后咱们参考 Envoy 官网压测领导 为 Envoy 增加一条路由:

static\_resources:  listeners:  - name: listener\_0    address:      socket\_address: { address: "0.0.0.0", port\_value: 10000 }    filter\_chains:    - filters:      - name: envoy.http\_connection\_manager        config:          generate\_request\_id: false,          stat\_prefix: ingress\_http          route\_config:            name: local\_route            virtual\_hosts:            - name: local\_service              domains: \["\*"\]              routes:              - match: { prefix: "/hello" }                route: { cluster: service\_test }          http\_filters:          - name: envoy.router            config:              dynamic\_stats: false  clusters:  - name: service\_test    connect\_timeout: 0.25s    type: LOGICAL\_DNS    dns\_lookup\_family: V4\_ONLY    lb\_policy: ROUND\_ROBIN    hosts: \[{ socket\_address: { address: "127.0.0.1", port\_value: 1980 }}\]    circuit\_breakers:      thresholds:        - priority: DEFAULT          max\_connections: 1000000000          max\_pending\_requests: 1000000000          max\_requests: 1000000000          max\_retries: 1000000000        - priority: HIGH        max\_connections: 1000000000        max\_pending\_requests: 1000000000        max\_requests: 1000000000        max\_retries: 1000000000

下面的 generate_request_id、dynamic_stats 和 circuit_breakers 局部,在 envoy 外部是默认开启,但本次压测用不到,须要显示敞开或设置超大阈值从而晋升性能。(谁能给我解释下为什么这玩意儿配置这么简单 -_-!)

压测后果

单条路由,不开启任何插件。开启不同 CPU 数量,进行满载压力测试。阐明:对于 Nginx 叫 worker 数量,envoy 是 concurrent ,为了对立前面都叫 worker 数量。

过程数APISIX QPSAPISIX LatencyEnvoy QPSEnvoy Latency
1 worker18608.40.9615625.561.02
2 workers34975.81.0129058.1351.09
3 workers52334.81.0242561.1251.12

注:原始数据公开在 [gist] 中。(https://gist.github.com/membp...

QPS:每秒钟实现的申请数,数量越多越好,数值越大代表单位工夫内能够实现的申请数量越多。从 QPS 后果看,APISIX 性能是 envoy 的 120% 左右,外围数越多 QPS 差距越大。

Latency:每申请的延迟时间,数值越小越好。它代表每申请从收回后须要通过多长时间能够接管到应答。对于反向代理场景,该数值越小,对申请的影响也就最小。从后果上看,envoy 的每申请提早要比 APISIX 多 6-10% ,外围数量越多提早越大。

能够看到两者在单工作线程|过程的模式下,QPS 和 Latency 两个指标差距不大,然而随着工作线程|过程的减少他们的差距逐步放大,这里我剖析可能有以下两方面的起因,nginx 在高并发场景下用多 worker 和零碎的 IO 模型进行交互是不是会更有劣势,另外一方面,也可能是nginx 本身在实现上面对内存和 CPU 的应用比拟“抠门”,这样累积起来的性能劣势,当前具体评估评估。

总结

总体来说 APISIX 在响应提早和 QPS 层面都略优于 Envoy, 因为 nginx 的多 worker 的合作形式在高并发场景下更有劣势,得益于此, APISIX 在开启多个 worker 过程后性能晋升较 Enovy 更为显著;然而两者并不抵触, Envoy 的总线设计使它在解决东西向流量上有独特的劣势, APISIX 在性能和提早上的体现使它在解决南北向流量上具备海量的吞吐能力,依据本人的业务场景来抉择正当的组件配合插件构建本人的服务才是正解。