When browsing the Internet, we all know that encryption via SSL is very important. In PayPal (PayPal), security is our first priority. We use end-to-end encryption, not just our public Web site, but also our internal service calls. The SSL encryption technology will affect the performance of node.js to a great extent. We have taken the time to adjust our external services and make full use of them. Here are some of the SSL configuration adjustments we've found that can significantly improve SSL's external performance.
SSL password
Out-of-the-box, Node.js SSL uses a very powerful set of cryptographic algorithms. In particular, Diffichelman key exchange and elliptic curve algorithms are extremely expensive. And when you use too much external SSL calls in the default configuration, Node.js's performance will be fundamentally compromised. To find out how slow it really is, here's a sample CPU for the service call:
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 ...
Let's focus on the key generation:
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
This call 87% of the time is spent on the build key!
These passwords can be changed to reduce intensive computations. This idea has been implemented in HTTPS (or proxy). For example:
var agent = new HTTPS. Agent ({
"key": Key,
"cert": Cert, "
ciphers": "aes256-gcm-sha384"
});
The above key has no use for expensive Diffichelman key exchange. After replacing it with something similar, we can see significant changes in the following examples:
...
57945.0ms 32.5% 16.0 ssl3_send_client_key_exchange
28958.0ms 16.2% 9.0 generate_key
26827.0ms 15% 2.0 Compute_key ...
Through the OpenSSL document, you can learn more about the cipher string.
SSL Session Recovery
If your server supports SSL session recovery, you can pass the session through HTTPS (or proxy). You can also wrap the agent's createconnection function:
var createconnection = agent.createconnection;
agent.createconnection = function (options) {
options.session = session;
Return Createconnection.call (agent, options);
By adding a brief handshake to the connection, session recovery can reduce the number of connections used.
Stay active
Allowing the agent to remain active will ease the SSL handshake. An agent that maintains activity, such as agentkeepalive, can fix the problem of node-keeping activity, but it is not necessary in Node0.12.
Another thing to keep in mind is the maxsockets of proxies, which can have a negative effect on performance. Control your Maxsockets value based on the number of external connections you create.
The size of the slab
Tls. Slab_buffer_size determines the allocation size of the slab buffers used by the TLS client (server). Its size defaults to 10MB.
These allocated intervals will expand your RSS feed and increase the time of garbage collection. This means that high capacity will affect performance. Adjusting this capacity to a lower value can improve memory and garbage collection performance. In version 0.12, the distribution of slab has been improved, and there is no need to adjust it.
Recent changes in SSL in 0.12
Test the SSL-enhanced version of Fedor.
Test instructions
Run an HTTP service that acts as an SSL service agent, running all on this computer.
v0.10.22
Running 10s Test @ http://127.0.0.1:3000/
threads and Connections
Thread Stats AVG Stdev Max/+-Stdev
L Atency 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 (built from major version)
Running 10s Test @ http://127.0.0.1:3000/
threads and 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< c15/>requests/sec:261.86
transfer/sec:27.62kb
There's not much difference, but this is due to the default password, so let's adjust the proxy option for the password. For example:
var agent = new HTTPS. Agent ({
"key": Key,
"cert": Cert, "
ciphers": "aes256-gcm-sha384"
});
v0.10.22
Running 10s Test @ http://localhost:3000/
threads and Connections
Thread Stats AVG Stdev Max/+-Stdev
L Atency 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
Re quests/sec:333.79
transfer/sec:36.83kb
V0.11.10-pre (built from major version)
Running 10s Test @ http://localhost:3000/
threads and 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
As we can see, after Fedor's modification, this has a huge difference: from 0.10 to 0.12 performance is about twice times worse!
Summarize
One might ask, "Why not just turn off the SSL and it will get faster when it's turned off" and for some people it's a choice. In fact, this is a fairly representative answer when I ask people how they solve SSL performance problems. However, if anything that the enterprise SSL requires increases and does not decrease, and although much has been done to improve SSL in Node.js, performance tuning is still needed. I hope that some of the above techniques will help you adjust the performance of SSL use cases.