インターネットを閲覧するとき、SSL による暗号化が非常に重要であることは誰もが知っています。 PayPal では、セキュリティが最優先事項です。当社では、公開 Web サイトだけでなく、内部サービス呼び出しにもエンドツーエンドの暗号化を使用しています。 SSL 暗号化テクノロジは、node.js のパフォーマンスに大きな影響を与えます。私たちは時間をかけて外部サービスを適応させ、最大限に活用してきました。以下は、SSL 外部パフォーマンスを大幅に向上させるために確認された、SSL 構成の調整のリストです。
SSL パスワード
Node.js の SSL は、すぐに使用できる非常に強力な暗号化アルゴリズムのセットを使用します。特に、Diffie-Hellman 鍵交換と楕円曲線アルゴリズムは非常に高価です。また、デフォルト構成でアウトバウンド SSL 呼び出しを多量に使用すると、Node.js のパフォーマンスが根本的に低下します。どれだけ遅いかを知るために、サービス呼び出しの CPU サンプルを次に示します。
918834.0ms 100.0% 0.0 node (91770) 911376.0ms 99.1% 0.0 start 911376.0ms 99.1% 0.0 node::Start 911363.0ms 99.1% 48.0 uv_run 909839.0ms 99.0% 438.0 uv__io_poll 876570.0ms 95.4% 849.0 uv__stream_io 873590.0ms 95.0% 32.0 node::StreamWrap::OnReadCommon 873373.0ms 95.0% 7.0 node::MakeCallback 873265.0ms 95.0% 15.0 node::MakeDomainCallback 873125.0ms 95.0% 61.0 v8::Function::Call 873049.0ms 95.0% 13364.0 _ZN2v88internalL6InvokeEbNS0 832660.0ms 90.6% 431.0 _ZN2v88internalL21Builtin 821687.0ms 89.4% 39.0 node::crypto::Connection::ClearOut 813884.0ms 88.5% 37.0 ssl23_connect 813562.0ms 88.5% 54.0 ssl3_connect 802651.0ms 87.3% 35.0 ssl3_send_client_key_exchange 417323.0ms 45.4% 7.0 EC_KEY_generate_key 383185.0ms 41.7% 12.0 ecdh_compute_key 1545.0ms 0.1% 4.0 tls1_generate_master_secret 123.0ms 0.0% 4.0 ssl3_do_write ...
鍵の生成に焦点を当てましょう:
802651.0ms 87.3% 35.0 ssl3_send_client_key_exchange 417323.0ms 45.4% 7.0 EC_KEY_generate_key 383185.0ms 41.7% 12.0 ecdh_compute_key
この通話の時間の 87% はキーの生成に費やされます。
これらのパスワードは、計算負荷を軽減するために変更できます。このアイデアは https (またはプロキシ) を使用して実装されています。例:
var agent = new https.Agent({ "key": key, "cert": cert, "ciphers": "AES256-GCM-SHA384" });
上記のキーは高価な Diffie-Hellman キーと交換されていません。これを同様のものに置き換えると、以下の例で大きな変化が見られます:
... 57945.0ms 32.5% 16.0 ssl3_send_client_key_exchange 28958.0ms 16.2% 9.0 generate_key 26827.0ms 15.0% 2.0 compute_key ...
暗号文字列について詳しくは、OpenSSL のドキュメントをご覧ください。
SSL セッションの再開
サーバーが SSL セッションの再開をサポートしている場合は、https (またはプロキシ) 経由でセッションを渡すことができます。プロキシの createConnection 関数をラップすることもできます:
var createConnection = agent.createConnection; agent.createConnection = function (options) { options.session = session; return createConnection.call(agent, options); };
セッションの再開では、接続にショート ハンドシェイク メカニズムを追加することで、使用される接続の数を減らすことができます。
アクティブに保ちます
プロキシが存続できるようにすると、SSL ハンドシェイクが容易になります。 Agentkeepalive などのキープアライブ エージェントを使用すると、ノードのキープアライブの問題を解決できますが、Node 0.12 では必要ありません。
もう 1 つ留意すべき点は、プロキシの maxSockets です。高い値はパフォーマンスに悪影響を与える可能性があります。作成する送信接続の数に基づいて maxSockets 値を制御します。
スラブサイズ
tls.SLAB_BUFFER_SIZE は、TLS クライアント (サーバー) によって使用されるスラブ バッファーの割り当てサイズを決定します。そのサイズのデフォルトは 10MB です。
これらの割り当てられた範囲により、RSS が拡張され、ガベージ コレクション時間が増加します。これは、大容量がパフォーマンスに影響を与えることを意味します。この容量をより低い値に調整すると、メモリとガベージ コレクションのパフォーマンスが向上します。バージョン 0.12 では、スラブ割り当てが改善され、それ以上の調整は必要ありません。
0.12 での SSL への最近の変更
Fedor の SSL 強化バージョンをテストします。
テスト手順
http サービスを SSL サービス プロキシとして実行し、すべてこのマシン上で実行します。
v0.10.22
Running 10s test @ http://127.0.0.1:3000/ 20 threads and 20 connections Thread Stats Avg Stdev Max +/- Stdev Latency 69.38ms 30.43ms 268.56ms 95.24% Req/Sec 14.95 4.16 20.00 58.65% 3055 requests in 10.01s, 337.12KB read Requests/sec: 305.28 Transfer/sec: 33.69KB
v0.11.10-pre (メインバージョンからビルド)
Running 10s test @ http://127.0.0.1:3000/ 20 threads and 20 connections Thread Stats Avg Stdev Max +/- Stdev Latency 75.87ms 7.10ms 102.87ms 71.55% Req/Sec 12.77 2.43 19.00 64.17% 2620 requests in 10.01s, 276.33KB read Requests/sec: 261.86 Transfer/sec: 27.62KB
これには大きな違いはありませんが、これはデフォルトのパスワードが原因であるため、パスワードのプロキシ オプションを調整しましょう。例:
var agent = new https.Agent({ "key": key, "cert": cert, "ciphers": "AES256-GCM-SHA384" });
v0.10.22
Running 10s test @ http://localhost:3000/ 20 threads and 20 connections Thread Stats Avg Stdev Max +/- Stdev Latency 59.85ms 6.77ms 95.71ms 77.29% Req/Sec 16.39 2.36 22.00 61.97% 3339 requests in 10.00s, 368.46KB read Requests/sec: 333.79 Transfer/sec: 36.83KB
v0.11.10-pre (メインバージョンからビルド)
Running 10s test @ http://localhost:3000/ 20 threads and 20 connections Thread Stats Avg Stdev Max +/- Stdev Latency 38.99ms 5.96ms 71.87ms 86.22% Req/Sec 25.43 5.70 35.00 63.36% 5160 requests in 10.00s, 569.41KB read Requests/sec: 515.80 Transfer/sec: 56.92KB
ご覧のとおり、ヒョードルの修正後は大きな違いがあり、0.10 から 0.12 までのパフォーマンスの差はほぼ 2 倍です。
概要
「SSL をオフにすれば高速になるのに、なぜオフにすればよいのですか?」と疑問に思う人もいるかもしれませんが、人によってはこれも選択肢になります。実際、これは、SSL のパフォーマンスの問題をどのように解決しているかを人々に尋ねたときの典型的な答えです。ただし、エンタープライズ SSL 要件がまったく増加していない場合、Node.js の SSL を改善するために多くのことが行われてきたとしても、依然としてパフォーマンスのチューニングが必要です。上記のテクニックのいくつかが、SSL ユースケースのパフォーマンスの調整に役立つことを願っています。