Beim Surfen im Internet wissen wir alle, dass die Verschlüsselung per SSL sehr wichtig ist. Bei PayPal steht Sicherheit an erster Stelle. Wir nutzen eine Ende-zu-Ende-Verschlüsselung nicht nur für unsere öffentliche Website, sondern auch für unsere internen Serviceaufrufe. Die SSL-Verschlüsselungstechnologie wird die Leistung von node.js stark beeinträchtigen. Wir haben uns die Zeit genommen, unsere externen Dienstleistungen anzupassen und das Beste daraus zu machen. Nachfolgend finden Sie eine Liste einiger SSL-Konfigurationsoptimierungen, die unserer Erfahrung nach die externe SSL-Leistung deutlich verbessern.
SSL-Passwort
SSL für Node.js verwendet standardmäßig einen sehr starken Satz kryptografischer Algorithmen. Insbesondere Diffie-Hellman-Schlüsselaustausch- und Elliptische-Kurven-Algorithmen sind extrem teuer. Und wenn Sie in der Standardkonfiguration zu viele ausgehende SSL-Aufrufe verwenden, wird die Leistung von Node.js grundlegend geschwächt. Um einen Eindruck davon zu bekommen, wie langsam es ist, finden Sie hier ein CPU-Beispiel eines Serviceaufrufs:
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 ...
Konzentrieren wir uns auf die Schlüsselgenerierung:
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 % der Zeit dieses Anrufs wird mit der Generierung von Schlüsseln verbracht!
Diese Passwörter können geändert werden, um sie weniger rechenintensiv zu machen. Diese Idee wurde mit https (oder Proxy) umgesetzt. Zum Beispiel:
var agent = new https.Agent({ "key": key, "cert": cert, "ciphers": "AES256-GCM-SHA384" });
Der obige Schlüssel wurde nicht gegen den teuren Diffie-Hellman-Schlüssel ausgetauscht. Nachdem wir es durch etwas Ähnliches ersetzt haben, können wir im folgenden Beispiel eine signifikante Änderung sehen:
... 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 ...
Weitere Informationen zu Chiffrierzeichenfolgen finden Sie in der OpenSSL-Dokumentation.
SSL-Sitzungsfortsetzung
Wenn Ihr Server die Wiederaufnahme einer SSL-Sitzung unterstützt, können Sie die Sitzung über https (oder einen Proxy) weiterleiten. Sie können auch die createConnection-Funktion des Proxys umschließen:
var createConnection = agent.createConnection; agent.createConnection = function (options) { options.session = session; return createConnection.call(agent, options); };
Die Wiederaufnahme der Sitzung kann die Anzahl der verwendeten Verbindungen reduzieren, indem der Verbindung ein kurzer Handshake-Mechanismus hinzugefügt wird.
Bleiben Sie aktiv
Wenn Sie zulassen, dass der Proxy am Leben bleibt, wird der SSL-Handshake vereinfacht. Ein Keep-Alive-Agent wie agentkeepalive kann das Node-Keepalive-Problem beheben, ist jedoch in Node 0.12 nicht erforderlich.
Eine weitere Sache, die Sie beachten sollten, sind die maxSockets des Proxys. Ein hoher Wert kann sich negativ auf die Leistung auswirken. Steuern Sie Ihren maxSockets-Wert basierend auf der Anzahl der von Ihnen erstellten ausgehenden Verbindungen.
Plattengröße
tls.SLAB_BUFFER_SIZE bestimmt die zugewiesene Größe des Slab-Puffers, der vom TLS-Client (Server) verwendet wird. Die Größe beträgt standardmäßig 10 MB.
Diese zugewiesenen Bereiche erweitern Ihr RSS und verlängern die Garbage Collection-Zeit. Das bedeutet, dass eine hohe Kapazität Auswirkungen auf die Leistung hat. Durch Anpassen dieser Kapazität auf einen niedrigeren Wert kann die Speicher- und Speicherbereinigungsleistung verbessert werden. In der Version 0.12 wurde die Plattenzuordnung verbessert und es sind keine weiteren Anpassungen erforderlich.
Neueste Änderungen an SSL in 0.12
Testen Sie die erweiterte SSL-Version von Fedor.
Testanleitung
Führen Sie einen HTTP-Dienst als SSL-Dienst-Proxy aus, der alle auf diesem Computer ausgeführt wird.
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 (Build aus der Hauptversion)
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
Das macht keinen großen Unterschied, aber das liegt am Standardpasswort, also passen wir die Proxy-Optionen des Passworts an. Zum Beispiel:
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 (Build aus der Hauptversion)
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
Wie wir sehen können, gibt es nach Fedors Modifikation einen großen Unterschied: Der Leistungsunterschied von 0,10 auf 0,12 beträgt fast das Zweifache!
Zusammenfassung
Manche Leute fragen sich vielleicht: „Warum SSL nicht einfach ausschalten, es wird schneller, wenn man es ausschaltet?“ Und für manche Leute ist dies auch eine Option. Tatsächlich ist dies eine ziemlich typische Antwort, wenn ich Leute frage, wie sie SSL-Leistungsprobleme lösen. Wenn die SSL-Anforderungen für Unternehmen jedoch alles andere als gestiegen sind und obwohl viel getan wurde, um SSL in Node.js zu verbessern, ist weiterhin eine Leistungsoptimierung erforderlich. Ich hoffe, dass einige der oben genannten Techniken Ihnen dabei helfen werden, die Leistung Ihrer SSL-Anwendungsfälle zu optimieren.