在CNCF組織的一場技術分享會上,第一次聽到了 Enovy 這麼一個東西,分享的嘉賓巴拉巴拉講了一大堆,啥都沒記住,就記住了一個特別新穎的概念「通訊總線」,後面 google 了下 Envoy 這個東西究竟是什麼,發現官網上如是描述:node
「Envoy 是專爲大型現代 SOA(面向服務架構)架構設計的 L7 代理和通訊總線」nginx
也就是說, Envoy 是爲了解決 Server Mesh 領域而誕生一款 L7 代理軟件,這裏我網上找了一張圖,我理解種的 Envoy 大概是以下的部署架構。(若是錯了請大佬指教)git
既然是L7的代理軟件嘛,做爲常年混跡 openresty 社區的老司機,天然忍不住把它拿來搞一搞,對比對比。github
咱們選擇的比試對象是最近剛從 Apache 社區畢業的 APISIX,它是基於 OpenResty 實現的 API 網關。(其實也就是 L7 代理而後加了路由、認證,限流、動態上游等等之類的功能)apache
爲何選擇它呢,由於有一次社區分享的時候據說這貨的路由實現很是棒,正好咱們的如今業務的路由系統亂七八糟,扒拉了下 APISIX 的源碼,發現確實是6到飛起,吊打我看到過的同類產品, 因此印象深入,就它了!ubuntu
這裏附上一張在 APISIX 官網扒拉的圖,真是一圖勝千言,一看就知道這玩意兒是怎麼工做的;api
開搞吧,首先咱們去官網找到兩個產品的最版本:服務器
Apache APISIX 1.5 和 Envoy 1.14網絡
這裏咱們用 nginx 搭建了一個上游服務器,配置 2 個 worker,接收到請求直接應答 4k 內容,參考配置以下:架構
server { listen 1980; access_log off; location = /hello { echo_duplicate 400 "1234567890"; } }
首先咱們找到 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 QPS | APISIX Latency | Envoy QPS | Envoy Latency |
---|---|---|---|---|
1 worker | 18608.4 | 0.96 | 15625.56 | 1.02 |
2 workers | 34975.8 | 1.01 | 29058.135 | 1.09 |
3 workers | 52334.8 | 1.02 | 42561.125 | 1.12 |
注:原始數據公開在 gist 中。
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 在性能和延遲上的表現使它在處理南北向流量上具備海量的吞吐能力,根據本身的業務場景來選擇合理的組件配合插件構建本身的服務纔是正解。