OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

如何提高NODE.js中SSL服务的性能


分享到


分类 编程技巧   发布 andrewleeson  1397222208967
注意 转载须保留原文链接,译文链接,作者译者等信息。  

(注* 尽管OpenSSL露出惊天漏洞,但是基于SSL的加密协议还是应用得最广泛的,这只是OpenSSL这个开源软件本身的问题(详情: OpenSSL是坑货写的),下面这篇文章提供了一些如何在NodeJS中,提高HTTPS性能方面的技巧)


在浏览互联网时,我们都知道,通过SSL进行加密是非常重要的。在贝宝(PayPal),安全是我们的首要任务。我们使用端到端的加密,不仅只是我们的公共网站,对于我们的内部服务调用也同样如此。SSL加密技术将在很大程度上影响node.js的性能。我们已经花时间调整我们的对外服务,并充分地利用他们。下面是一些我们发现能显著地提高SSL对外性能的SSL配置调整清单。

 

SSL密码


开箱即用,Node.js 的SSL使用一组非常强大的密码算法。特别是,迪菲赫尔曼密钥交换和椭圆曲线算法是极其昂贵的。而且当你在默认配置中用了太多的对外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会话恢复,那么你可以通过https(或代理)来传递会话。你也可以将代理的createConnection函数包裹起来:

var createConnection = agent.createConnection;

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

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


保持活动

 

允许代理保持活动将缓和SSL握手。一个保持活动的代理,比如agentkeepalive可以修复结点保持活动的问题,但在Node0.12中它是非必须的。

 

另一个需要铭记在心的东西是代理的maxSockets,这个值高的话能对性能造成负面的影响。在你创建的对外连接数量的基础上控制你的maxSockets值。

 

Slab的大小

 

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

 

这些分配的区间将会扩展你的rss且会增加垃圾回收的时间。这意味着高容量将会影响到性能。把这个容量调整到一个比较低的值可以改善内存和垃圾收集的性能。在0.12 版本中,slab的分配已经得到改善了,没有必须再调整了。


SSL在0.12中近期的改变

 

测试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用例性能。

原文地址: 点此
社区评论 ( Beta版 )
  • #0 redstone 1398042681000
    用nginx的ssl来代理Node.js的web服务会不会更高效,很简单直观。
  • #1 隔心岛 1398086783000
    @redstone

    nginx只能提供静态文件服务吧
  • #2 redstone 1400115320000
    @隔心岛

    nginx可以做代理啊,简单的很,几行配置就可以了。
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. NODE.JS为什么会成为企业中的首选技术
  2. 快乐Node程序员的10个习惯
  3. 我为什么不从NodeJS切换到Go
  4. 用纯CSS实现的箭头
  5. 在JavaScript里写类层次结构?别那么做!
  6. 静态web的回归
  7. HTML和CSS是什么玩意儿?
  8. 为什么优秀的管理者如此罕见
  9. 没必要害怕Angular.Js
  10. 一系列JavaScript的基础工具
  11. 用 OnceAir 搭建个人Git/Svn/照片备份服务器,每年电费7块钱

 相关阅读 - 编程技巧
  1. PHP开发者常犯的10个MySQL错误
  2. 一些达成共识的JavaScript编码风格约定
  3. 写给 Node.js 学徒的 7 个建议
  4. 优秀工具推荐:超实用的 CSS 库,样板和框架
  5. NodeJS on Nginx: 使用nginx反向代理处理静态页面
  6. 高级JavaScript调试—— console.table()
  7. 技术干货:Nginx 战斗准备 — 优化指南
  8. 性能测评:Ngix_Lua, Node.JS Python三者性能相当,均比php快近一倍
  9. 代码审查:写出好的 commit message
  10. 永远不要在Linux执行的10个最危险的命令

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号