Node v1.0 路线图

  • 田永强

2013 年 5 月 20 日

话题:JavaScriptNode.js语言 & 开发架构

在上周(5.9)于 San Francisco, CA,由 Node.js++ 俱乐部举办的分享会议上,Isaac Schlueter(Node 现今的 Gatekeeper)介绍了 Node v1.0 的详细路线图,并于Youtube 上传了分享视频。Isaac Schlueter 在本次分享中介绍了 Node1.0 发布前 Node 还将经历的增强和改动。这个经历 4 年左右发展的技术,一出世就吸引了太多太多的目光,惊人的社区活力,相信它的大版本会得到更多人的关注。

尽管 Isaac Schlueter 在 Node v0.10 发布时就对未来的计划通过博客进行过说明,但没有本次分享详细和正式,那让我们就内容先睹为快吧。

Node v0.10

Node v0.10 的发布,带来了以下这些改进,并随着 v0.10.x 的发布,将持续在这几个方面带来增强:

  • 主要引入了新的 Stream API(Stream2)
  • API 的改进。包括 domains, nextTick, IdleGC 等
  • 持续集成。目前 Node通过 jenkins 搭建了持续继承的环境,每天为新的改动执行单元测试,以检测对多个平台的影响
  • 一些企业场景的支持
  • 依然成指数增长的社区模块

这里 Stream2 主要方向是内部重构和向下兼容方面的工作,不再重点详述。

npm-www 的计划

npm-www是 Node 官方的第三方公共模块平台,目前上面有 3 万多个第三方模块,在数量和开发速度上都呈现出社区的活跃度。但是这里隐藏的问题是第三方模块存在良莠不齐的质量,需要更科学的管理,和更良好的社区生态环境。Isaac Schlueter 提到将会通过以下三个方面入手:

  • 集成 Github。集成 Github 上的项目仓库,和集成 Github 的登录。npm 上的模块大多托管在 Github 上,集成 Github 将两个社区联系得更紧密
  • 推荐引擎。目前寻找目标模块的方式还比较原始,主要是通过 Node 的模块列表 Wiki、通过 npm-www 搜索、通过 Github 等。对于社区的发展还需要更好的推荐方式,如何让优秀的模块让需要它的人更快的找到,是故,推荐引擎不可少。
  • 模块排行。Isaac Schlueter 计划引入 CPAN 社区中的“Kwalitee”风格来让模块进行排序。

“Kwalitee”是一个拟声词,发音与“quality”相同。CPAN 社区对它原始的解释如下:

"Kwalitee" is something that looks like quality, sounds like quality, but is not quite quality.

总体意思就是模块的质量不是那么容易确认,只能从一些层面对它进行考察,但即使考察都通过,也并不能意味着它就是高质量的模块,所以存在“Kwalitee”这么一个新发明的词。这个方法能排除大部分不合格的模块,虽不精确,但是有效。总体而言,符合“Kwalitee”的模块应该是满足如下的条件:

  • 具有良好测试
  • 具有良好文档(README、API)
  • 具备良好的测试覆盖率
  • 具备良好的编码规范
  • etc.

对 API 采用 Deprecate 标记, 而不是暴力修改 API

没有人料到 Node 目前已经这么成熟,随着 Node 的成长,刻意破坏 API 兼容性的日子结束了。假如发现 Node 中有些 API 不合理,也不会直接暴力删除了,而是采用温和的 deprecate 标记。Node 团队保证只要你的应用现在能跑起来,不用任何修改过了一年以后仍然能跑起来。

Node v0.12

对于 v0.12,可以将它看成是 1.0 的候选版本。这个版本之后,就是我们翘首企盼了 4 年的 1.0 版本。这个版本主要的工作几种在 4 个方面:

  • 重构 TLS 模块。主要是在性能方面
  • 清理 HTTP 模块
  • 提升 Cluster 模块的负载均衡能力
  • 处理掉 Buffers 中性能慢的点

Buffers

Buffers 是这个版本要重点攻克的地方,因为 Buffers 在 Node 中有着广泛的应用,任何 Buffers 带来的性能提升都会让 Node 受益。现在的难点在于 Persistent和 MakeWeak 的 GC 方式太慢。

目前调研了两种方法来解决这个问题:

  • ThinBuffers。一种用户分配 / 销毁的的 Buffers 对象
  • 让 Buffer 成为 V8 的原生对象,视图从 V8 的层面来改进

不久之前,Trevor Norris 加入了 Node 核心开发团队。Trevor Norris 来自 Mozilla 公司,之前为 Node 贡献的开发工作主要在 node.cc 中,围绕 process.nextTick, node::MakeCallback 和 Domains 部分。他的加入主要是致力让 Buffers 更快。让我们翘首以待。

TLS

TLS 模块是 Node 典型的弱点。由于涉及安全,在系统中存在更多的层次。完成一次安全传输,TSL 是先要经过 libuv(C),进入 TCP 层(JavaScript),处理的结果立刻扔给 OpenSSL(C),OpenSSL 干完活后又扔出 Buffer,给后面的 http_parser,处理之后才扔出 Buffer 给用户层(JavaScript)。如图所示:

我们可以看到这这过程中有大量的 JavaScript 与 C 之间的对象调用,中间创建了大量无意义的 Buffer。所以将会对 TLS 中的 tls.CryptoStraeam 进行重构。重构后这一层,以下的代码全部用 C 完成,这以上的代码全用 JavaScript 完成,这样只要创建一次 Buffer 就可以了。

将来 tls.CryptoStream 会为了向下兼容而存在,不会被默认启用。

http

http 模块目前一个文件中既包含服务端也包含客户端代码,主要的目的是试图共用一些代码,但这并不是一个好主意。目前已经着手分离它,以使代码更容易管理。同时 http 模块与 TLS 有相同的问题,就是创建了太多无意义的 Buffers 对象,这也是待改进的点。

对于 http 客户端的连接池,Node 默认设置的连接数量是 5,这个数字可能是当时拍脑袋决定的,该版本将会改进它。

另外 http 的客户端实现只在队列中有请求时,才让底层 TCP 保持连接,如果队列中没有请求,就会关掉它,即是你立即又发起请求。这个版本的改进将使它真正能保持连接。

cluster

cluster 模块使得 Node 能够实现单机的进程集群,但它目前在负载均衡上的表现欠佳,总有一个或两个 worker 进程干了太多活。这使得你需要集群好好工作的地方,却在某些情况下引起问题。接下来的解决方案是将会采用 round-robin 调度来使集群负载均衡良好。

其他地方

  • 子进程同步执行 execSync
  • 流对象写入的 writev 支持(将多个缓冲区中的数据一次写出,以提升性能)
  • V8 API 改变带来的某些改变
  • 更好的 IPv6 支持
  • 特殊的 DNS 支持
  • Bug 修复等

Node v1.0

Node v1.0 将是 v0.12 之后的下一个稳定版,目前的 API 在 1.0 中都会有效,但是内部会有小的改动。v0.12 版本之后不会新的功能特性开发计划,从 0.12 到 1.0 之间不会有大体上的区别。

总结

总体来说,这个路线图主要反映如下这几个方向: - 持续性的稳定系数提升 - 速度提升,这可能得益于 V8 的升级,或者新的 ECMAScript 特性等 - Node 现在已经相当稳定,可以放心使用。 - 不会有奇怪的事情发生 - Node 绝不会出现 Perl6/Python3(不会出现语法变动,不向下兼容的版本)

另外 Node v1.0 之后会带来稳定和持续性的发展势能,这主要体现在: - Node 国度中,对核心代码的改动影响将会减缓 - 稳定的基础是最好的培养社区创新的最好方式 - 仍然可能发生变化,虽然是稳定的立场相悖,但会做出权衡 - 疯狂而高产,快速成长的社区 - 涌现更多用 Node 的产品将势不可挡

参考


感谢崔康对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

JavaScriptNode.js语言 & 开发架构