Node.js SSL性能优化实战:密码、会话与内存配置

作者:岩茶

时间:2026-10-28

浏览:527

本文深入解析Node.js中SSL服务的性能瓶颈,重点分析高开销的密钥交换算法对CPU的影响。通过调整密码套件、启用会话恢复及优化Slab缓冲大小,可显著提升HTTPS服务吞吐量。结合Node.js 0.12版本的改进实测,展示了优化后性能翻倍的效果,为高并发场景下的安全连接提供实用配置建议。

文章目录

Node.js SSL性能优化概述

在互联网浏览中,通过SSL进行加密至关重要。以PayPal为例,安全是其首要任务,不仅公共网站,内部服务调用也采用端到端加密。然而,SSL加密技术会显著影响Node.js的性能。我们对对外服务进行了充分调整,以下列出能显著提升SSL对外性能的几项关键配置调整。

SSL密码配置优化

SSL密码配置

Node.js默认使用一组非常强大的密码算法,包括迪菲-赫尔曼(Diffie-Hellman)密钥交换和椭圆曲线(EC)算法,这些计算极其昂贵。如果在默认配置下进行大量对外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"
});

上述配置移除了昂贵的迪菲-赫尔曼密钥交换,替换为等效选项。从下面的示例中可以看到显著的性能变化:


...
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会话恢复 如果服务器支持SSL会话恢复,可以通过HTTPS代理传递会话。此外,还可以包裹代理的createConnection函数:


var createConnection = agent.createConnection;

agent.createConnection = function (options) {
  options.session = session;
  return createConnection.call(agent, options);
};

通过为连接增加简短的握手机制,会话恢复能有效降低连接数使用。

保持活动(Keep-Alive) 启用代理的保持活动功能可以缓解SSL握手压力。使用如agentkeepalive这样的代理可以修复Node.js的保持活动问题,但在Node 0.12中这已非必需。

另一个需要注意的点是代理的maxSockets值。如果该值过高,会对性能产生负面影响。应根据创建的对外连接数量来控制maxSockets的值。

Slab缓冲大小调整

Slab缓冲大小 tls.SLAB_BUFFER_SIZE决定了TLS客户端(或服务器)使用的slab缓冲区分配大小,默认值为10MB。

这些分配区间会扩展RSS(常驻集大小)并增加垃圾回收时间,意味着高容量会影响性能。将容量调整至较低值可以改善内存和垃圾收集性能。在Node 0.12版本中,Slab分配已得到改善,无需再手动调整。

Node.js 0.12版本改进与测试

Node.js 0.12中SSL的近期改进 测试Fedor的SSL增强版。

测试说明

运行一个作为SSL服务代理的HTTP服务,全部运行在本机上。

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

正如我们所见,经过Fedor的修改,这有着巨大的区别:从0.10到0.12性能差不多差着2倍左右!

总结

总结

有人可能会问“为什么不仅仅只是关掉SSL呢,关了之后它就会变得快起来”,且对于一些人来说这也是一种选择。实际上,当我问别人他们是如何解决SSL性能问题的时候这是比较有代表性的答案。但是,如果企业SSL要求的任何东西只增加不减少;且尽管已经做了很多来改善Node.js中的SSL,性能调整仍然还是需要的。我希望上述的一些技艺能够帮助你调整SSL用例性能。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章