ブログ | NGINX

NGINX コントローラー API 管理モジュール vs. コング: パフォーマンス比較

NGINX-F5 水平黒タイプ RGB の一部
ファイサル・メモン サムネイル
ファイサル・メモン
2019年5月6日公開

API 管理 (APIM) 市場は競争が激しい分野です。 フルライフサイクル API 管理に関する最新の Gartner Magic Quadrant では、 22 社のベンダーがランク付けされ、そのうち 7 社がリーダー クアドラントにランクされています。 既存の市場で競争するには、競合他社と差別化し、目立つ強力な地位を確立する必要があります。 では、NGINX のAPI 管理ソリューションは何が違うのでしょうか?

NGINX の目標は、軽量で高性能なソフトウェアを作ることです。 NGINX オープンソースは、イベント駆動型アーキテクチャが接続ごとにプロセスやスレッドを生成する Web サーバーよりも優れた拡張性を備えているため、世界で最もアクセスの多いサイトで頼りになる Web サーバーとなっています。 NGINX オープンソースは、業界で最も普及している API ゲートウェイでもあり、Apigee、Axway、IBM DataPower、Kong、 Red Hat 3scale 、Torry Harris などの APIM ソリューションで API トラフィックを処理するインフラストラクチャ コンポーネントです。

NGINX コントローラー API 管理モジュールは、高性能な APIM ソリューションです。 このブログでは、そのパフォーマンスを、その高いパフォーマンスで知られる競合製品である Kong と比較します。 Kong は NGINX 上に構築されており、Lua を使用して API 機能を実装しますが、API 管理モジュールは、NGINX Plus モジュールとして実装されているネイティブの高パフォーマンス機能に完全に依存しています。 NGINX の API 管理ソリューションは、データ プレーンとコントロール プレーンを分離する革新的なアーキテクチャに基づいて構築されています。 すべての API 呼び出しは、コントロール プレーンとのやり取りを必要とせずに、API ゲートウェイ (データ プレーン) として機能する NGINX Plus によって直接処理されます。 これにより、南北トラフィックと東西トラフィックの両方で高性能な API トラフィック仲介が実現します。

結果のプレビュー: NGINX コントローラー API 管理モジュールは Kong より 2 倍優れています。

このテストを行うために使用されたハードウェアとラボスペースを提供してくれたIntelに特に感謝します。 完全なテストとハードウェアの詳細については、付録を参照してください。

単一のリクエストに追加されるレイテンシ

このテストでは、サイズが0 KBと 1 KBのファイルに対して、API マネージャーによって導入される追加のレイテンシを単一のリクエストと比較しました。 単一の HTTP リクエストを送信するためにcurl を使用しました (詳細)。

Kong では、API 管理モジュールと比較して、レイテンシが増加します。0 KB のファイルの場合は 44%、 1 KB のファイルの場合は 24% 増加します。

1秒あたりのAPI呼び出し数

標準的な HTTP スケーラビリティ メトリックは、1 秒あたりのリクエスト数 (RPS) です。 APIM のコンテキストにおける同等のメトリックは、1 秒あたりの API 呼び出し数です。 私たちは、 wrk を使用して、 0 KBまたは 1 KB のファイルに対するリクエストの連続ストリームを 300 回の接続で 3 分間送信しました (詳細)。

API 管理モジュールのパフォーマンスは Kong を上回り、 1 KB の応答に対して1 秒あたり 2.6 倍の API 呼び出しを処理しました。

CPU使用率

API 管理モジュールは CPU をより効率的に使用するため、Kong よりもレイテンシが少なくなり、1 秒あたりに処理できる API 呼び出しの数が増えます。 1 秒あたりの API 呼び出し回数を増やしながら CPU 使用率を測定しました。 使用したコアは 1 つだけなので、1 秒あたりの API 呼び出しの絶対数は、22 個のコアを使用した前回のテスト (詳細) よりも大幅に少なくなります。

Kong は実質的に 1 秒あたり 5,000 回の API 呼び出しで上限に達します。呼び出し量がこれ以上になると、レイテンシーが著しく上昇し、システムがフルロード状態であることを示します。 1 秒あたり 5,000 回の呼び出しでは、CPU 使用率は 93% となり、API 管理モジュールよりも 73% 高くなります。

JWT を使用した 1 秒あたりの API 呼び出し数

最終テストでは、API リクエストの認証に推奨される方法である JSON Web Token (JWT) を各 API ゲートウェイがどの程度検証できるかを測定します。 最も重要な API エンドポイントは認証される可能性が高いため、このテストは実際の構成に近いものになります。

両方のゲートウェイで、HS256 を使用して署名された同じ JWT を使用しました (詳細)。

API 管理モジュールは、Kong と比較して 1 秒あたり 2 倍以上の JWT 認証 API 呼び出しを処理します。

NGINX コントローラーの仕組み

NGINX コントローラーは、NGINX Plus データ プレーンを管理するコントロール プレーン ソリューションです。 NGINX コントローラーを使用すると、サービス メッシュ環境のロードバランサー、API ゲートウェイ、またはプロキシとして、NGINX Plus のライフサイクル全体を管理できます。 NGINX コントローラーの API 管理モジュールを使用すると、API を定義、公開、保護、監視、分析できます。

内部的には、NGINX コントローラーは、基盤となる NGINX Plus データ プレーンに公開される NGINX Plus 構成を生成します。 コア構成ローダーには、構成をメモリに保存するための非常に効率的なメカニズムがあり、API 管理モジュールが API に高いパフォーマンスを提供できるようになります。

結論

多くの企業がすでに API ゲートウェイとして NGINX Open Source を使用しています。 Capital One は、NGINX Open Source を使用して、 1 日あたり 120 億回を超える API 呼び出しに拡張することができました。 実際、Kong を含む多くの競合他社は、APIM ソリューションの内部で NGINX オープンソースを使用しています。 ネイティブで高性能な NGINX 構成と NGINX Plus モジュールに基づく当社の軽量設計により、API 管理モジュールは NGINX 派生の競合製品よりも優れた拡張性を実現します。

レイテンシは、エンドユーザー エクスペリエンスにとって最も重要な指標の 1 つです。 遅延が長いとアプリの応答性が低下し、ユーザーにストレスを与えます。 API 管理モジュールを使用すると、Kong と比較してユーザー リクエストのレイテンシが 20~30% 減少します。 また、システム リソースをより効率的に使用し、同じワークロードで Kong よりも CPU の使用量が 40% 少なくなります。


付録

トポロジー

すべてのテストは、シンプルでフラットなレイヤー 2 ネットワーク内の 10 GbE リンクで接続された 3 台の個別のマシンを使用して実行されました。

使用されるハードウェア

テストには次のハードウェアが使用されました。 3 台のマシンはすべて同一でした。 ハイパースレッディングは使用されませんでした。 以前のテストでは、ハイパースレッディングによるパフォーマンスの大きな違いは見られませんでした。

CPU ネットワーク メモリ
Intel® Xeon(R) CPU E5‑2699 v4 @ 2.20GHz、22 コア インテル イーサネット コントローラー 10 ギガビット X540-AT2 128GB

使用ソフトウェア

テストには次のソフトウェアを使用しました。

  • NGINX コントローラー API 管理モジュール バージョン 2。
  • Kong オープンソース バージョン 1.0.0。 Kong Enterprise はテストしていませんが、その追加機能はいずれもテストとは関係ありません (たとえば、Kong Open Source と Kong Enterprise は同じ JWT プラグインを使用します)。
  • curlバージョン 7.61.0。
  • Dockerバージョン18.09.1。 管理を容易にするために、Kong と API 管理モジュールの両方を Docker コンテナ内で実行しました。 Docker を使用するとパフォーマンスが約 30% 低下することがわかりましたが、相対的なパフォーマンスを比較しているため、Docker を使用するメリットがパフォーマンスの低下を上回りました。
  • systatパッケージのバージョン 12.0.1 のmpstat
  • wrkバージョン 4.1.0、これらの手順に従ってインストールされました。

NGINX 設定

テストには次の NGINX 構成が使用されました。

アップストリーム my_upstream { keepalive 60; サーバーAPI-server :80; keepalive_requests 3000000; keepalive_timeout 300; } サーバー { listen 8000; access_log off; keepalive_requests 3000000; keepalive_timeout 300; tcp_nodelay on; location /test { set $apimgmt_environment 4; set $apimgmt_definition 3; set $upstream my_upstream; set $upstream_protocol http; rewrite ^ /_devel_4 last; } location = /_devel_4 { internal; set $apimgmt_definition_name my_api; set $apimgmt_environment_name devel; proxy_intercept_errors on; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_pass $upstream_protocol://$upstream/0kb; # 0 KB のファイル #proxy_pass $upstream_protocol://$upstream/1kb.bin; # 1 KB のファイル } }

パフォーマンスを最大化するために、以下の設定を行いました。 次のセクションで詳しく説明するように、Kong 構成でも同様の設定を行いました。

  • TCP 接続のセットアップによるオーバーヘッドを最小限に抑えるために、 keepalive_requestskeepalive_timeout は高い数値に設定されました。
  • tcp_nodelayが有効になり、Nagle アルゴリズムを無効にすることでパフォーマンスがわずかに向上しました。
  • access_log が無効になりました。 有効にするとパフォーマンスが約 10% 低下します。
  • 適切なファイル サイズを要求するために、2 つのproxy_passディレクティブを使用しました。

Kong の構成

前のセクションで説明した NGINX 構成の設定と一致するように、次の構成ディレクティブをkong.conf.defaultに追加しました。

nginx_http_tcp_nodelay=オンnginx_http_keepalive_requests=3000000
nginx_http_keepalive_timeout=300
proxy_access_log=オフ

API サーバーへのルートを作成するために、次の Kong API 呼び出しを実行しました。 最初のコマンドはtestという名前のサービスを作成し、2 番目のコマンドはサーバーを指すルート/testを作成します。

$ curl -X POST http://localhost:8001/services/ \ --data 'name=test' \ --data 'url=http:// API-server :80/0kb' $ curl -X POST http://localhost:8001/services/test/routes \ --data 'paths[]=/test'

次のコマンドは、それぞれサービスとルートの設定を表示します。 JSON 出力を読みやすくするために、出力をjqツールにパイプします。

$ curl localhost:8001/services/ | jq '.' { "next": null, "data": [ { "host": "172.20.40.32", "作成日時": 1556770191、「接続タイムアウト」: 60000、「id」: 「f4629d56-550b-4b37-aa59-66d931aa6f37」、「プロトコル」: 「http」、「名前」: 「test」、「read_timeout」: 60000、「ポート」: 80、「パス」:「/0kb」、「更新日時」: 1556770191、「再試行」: 5、「書き込みタイムアウト」: 60000 } ] } $ curl localhost:8001/services/test/routes | jq '.' { "next": null, "data": [ { "created_at": 1556770191、「メソッド」: null、「id」: "a7b417af-ccd4-48f7-b787-ae19490194dc」、「サービス」: { 「id」: "f4629d56-550b-4b37-aa59-66d931aa6f37" }、「名前」: null、「ホスト」: null、「更新日時」: 1556770191、「preserve_host」: false、「regex_priority」: 0、"paths": [ "/test" ]、"sources": null、"destinations": null、"snis": null、"protocols": [ "http", "https" ]、"strip_path": true } ] }

テスト方法

単一のリクエストに追加されるレイテンシ

単一リクエストのレイテンシテストにはcurl を使用しました。 ベースラインを設定するために、まず API ゲートウェイを介さずに API サーバーにリクエストを送信しました。 次に、API サーバーの前にある各 API ゲートウェイに同じリクエストを送信し、発生したレイテンシを測定しました。

$ curl -w "@curl-latency.txt" -o /dev/null -s http://ターゲットサーバー

curl-latency.txtの内容:

    time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n

単一のリクエストに追加されたレイテンシのグラフには、 time_total がミリ秒単位で表示されます。 出力例は次のとおりです。

$ curl -w "@curl-latency.txt" -o /dev/null -s http://192.0.2.1/api-endpoint time_namelookup:  0.000035 接続時間:  0.000364 時間_アプリ接続:  0.000000 事前転送時間:  0.000401 リダイレクト時間:  0.000000 転送開始時間:  0.001701 ---------- 合計時間:  0.001727

1秒あたりのAPI呼び出し数

私たちは、頻繁に使用するスケーラブルなベンチマーク ツールであるwrk を使用して、1 秒あたりの API 呼び出しをテストしました。 さまざまなパラメータの組み合わせを試しましたが、次の組み合わせで API 管理モジュールと Kong の両方のパフォーマンスが最大化されました。

$ wrk -t 22 -c 300 -d 180 http://ターゲットサーバー

このコマンドは、22 個のwrkスレッド (コアごとに 1 つ) と、スレッド全体で合計 300 個の接続を作成します。 -dパラメータはテストの継続時間を指定します。この場合は 180 秒 (3 分) です。 サンプル出力:

$ wrk -t 22 -c 300 -d 180 http://192.0.2.1/api-endpoint 3 分間のテストを実行中 @ http://192.0.2.1/api-endpoint 22 スレッド、300 接続 スレッド統計 平均標準偏差 最大 +/- 標準偏差 レイテンシ 13.96ms 7.84ms 279.85ms 77.37% 要求/秒 0.96k 298.23 1.88k 68.55% 3.00m で 3769861 件の要求、36.25GB 読み取り 要求/秒:  20934.34 転送/秒:    206.16MB

CPU使用率

1 秒あたりの API 呼び出し数を調べるためにwrkコマンドを実行しながら、 mpstat (この目的のための標準 Linux ツール) を使用して CPU 使用率をテストしました。 サンプル出力(読みやすくするために 2 行に分割されています):

$ mpstat Linux 4.18.0-13-generic (nbdw38) 04/29/2019 _x86_64_ (88 CPU) 03:34:50 PM CPU %usr %nice %sys %iowait %irq %soft %steal ...
午後 3:34:50 すべて 0.04 0.00 0.02 0.00 0.00 0.03 0.00 ... ... %guest %gnice %idle ...   0.00 0.00 99.91

JWT を使用した 1 秒あたりの API 呼び出し数

1 秒あたりの API 呼び出しについてwrkコマンドを使用し、JWT のパフォーマンスをテストしました。 -Hパラメータを追加して、 Authorization に JWT を挿入しました。 ベアラーHTTP ヘッダー。 このブログ投稿の指示に従って JWT と JSON Web キー (JWK) を生成し、JWT をtest.jwtというファイルに保存しました。

$ wrk -t 22 -c 300 -d 180 -H "認証: ベアラー `cat test.jwt`" \ http://ターゲットサーバー

「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"