写点什么

Node.js V0.12 新特性之在单进程中跑多个实例

  • 2014-04-01
  • 本文字数:1962 字

    阅读完需:约 6 分钟

实例

经常有人提出,希望 Node.js 能被嵌入到其他程序中,特别是让它能跟其他事件循环整合而且(与此同时)支持多个 Node 执行情境:也就是说让多个 Node 实例在同一个进程中和平共处的能力。想象一下,比如有个 node-webkit 程序,每个窗口都运行在自己的 Node 实例上,各窗口彼此相互独立。或者把 Node 嵌在手机或网络交换机里,处理多连接的路由逻辑,但却只是在单个进程中,并且不久的将来就能实现。

一个客户找到我们,说他们的程序需要这类功能。他们经过调研,肯定了我们在 Node 核心和 libuv 上的贡献和专业能力,决定请我们帮忙。这是个相当有挑战性的订单,因为Node 一开始就是- 并且现在仍然是- 一个单线程的程序,围绕着单一事件循环的概念构建,用上百个全局变量存放各种状态。

你可以想象一下,在这样的代码库上加装线程安全是多么容易出错的任务,所以那不是我们要做的- 或者说我们还没那么做。我们希望这个修改对客户来说经济实惠,并且向前迈出这一步也能帮到整个社区。顺便说一下,如果你发现自己需要对Node 做些修改,可自己又没时间研究该怎么改,我们可以帮忙!

引入多情境

实际上,我们在Node v0.12 中实现了在同一个事件循环中使用多个执行情境的能力。别担心:对普通用户来说并没有显性的变化,一切都和以前一样。但如果你是嵌入开发人员,或本地附加组件作者,请继续往下看!

提交 756b622 中的“多情境”工作是第一次,也是最重要的清理任务:它把所有全局变量审了一遍,首先去掉了那些不需要放在全局中的变量,并将剩下的变成了执行情境的属性。虽然那还不足以保证线程安全,但这第一步很重要。

第二步是让 Node 内部意识到多执行情境的存在。C++ 运行时在任何地方进入 V8 VM,都要先确保它进入的是正确的情境。下面是一个简单的例子:

复制代码
function onconnect() {
this.write('GET / HTTP/1.1\r\n' +
'Host: strongloop.com\r\n' +
'\r\n');
this.pipe(process.stdout);
}
require('net').connect(80, 'strongloop.com', onconnect);

Execution-wise,差不多应该是这个样子的:

复制代码
<enter VM>
connect(80, 'strongloop.com'); // kernel reports EINPROGRESS here
<leave VM>
<wait for TCP handshake to complete>
<enter VM>
onconnect();
<leave vm>

在进入 VM 的调用之间可能会改变执行情境。因此 connect() 有必要记住当前情境,并且调用 onconnect() 能恢复它。如果做不到这一点,追踪 bug 将会变得极其困难。

好在 Node 可以自动把这个处理好;嵌入开发人员和本地附加组件作者不需要担心这个,除非他们想用 v8::Function::Call() 代替 node::MakeCallback() 进入 VM 做调用。

如果你是本地附加组件作者,想让你的附件组件具备识别情境的能力,你需要:

复制代码
* Instead of NODE_MODULE(), use
NODE_MODULE_CONTEXT_AWARE(). Before:
void Initialize(v8::Handle<v8::Object> exports) {
// ...
}
NODE_MODULE(foo, Initialize)

之后:

复制代码
void Initialize(v8::Handle<v8::Object> exports,
v8::Handle<v8::Value> module,
v8::Handle<v8::Context> context) {
// ...
}
NODE_MODULE_CONTEXT_AWARE(foo, Initialize);

能识别情境的初始化方法在嵌入创建的每个情境都会被调用一次。现在还没有各情境的清理函数,最终会由 node::AtExit() 承担这一职责,但目前还是一个针对进程的事件。如果对你来说这样不行,请在这里提交个bug。

将全局变量变成各情境的属性有几种办法,其中一个是为你自己宣称一个嵌入数据索引,并把所有东西都存在那里。

这些索引还没有全局注册表,所以仍有发生冲突的可能。有没有想试着给打个补丁?同时挑一个差不多大的随机数(比如2^10 到2^16 之间的),但不要太极端:V8 用一个非稀疏矩阵作为嵌入索引的内部存储。将索引宣称为1 << 29 就会消耗很多内存!

还有多少工作要做?

这里还有些粗糙的边界需要打磨:process.chdir() 会改变所有情境的工作目录,但实际上应该只改变调用它的情境的工作目录;从多情境中加载附加组件还有些边界情况,等等诸如此类的地方。但那属于修修补补力求尽善尽美的工作了。基本框架已经到位了,并且那家赞助我们开发多情境特性的公司已经成功地用上它了。更重要的是,它为多线程多重租赁铺平了道路。那在Node v0.12 之前不太可能发生了,但我们可能会在Node v1.0 或另一个版本中见到它- 只要我们敢!

作者简介

本文最初由 Ben Noordhuis 发表在 StrongLoop 上。Ben Noordhuis 从 2010 年就跟着 Ryan Dahl 开发 Node.js 的核心代码。他一直在为改进 Node 核心代码而努力做着编码、调试和基准测试等工作。作为最高产的 Node 核心开发者之一,Ben 编写了 Node.js 和 libuv 中的很多代码。 StrongLoop 降低了在 Node 中开发APIs 的难度,还添加了监测、集群化以及私有注册的支持等DevOps 能力。

查看英文原文: What’s New in Node.js v0.12 – Running Multiple Instances in a Single Process

2014-04-01 22:564621
用户头像

发布了 45 篇内容, 共 26.6 次阅读, 收获喜欢 11 次。

关注

评论

发布
暂无评论
发现更多内容

体系完整的数智化底座支撑企业创新发展,实现国产替代

用友BIP

国产替代

持续推进平台化、生态化用友助力数智化安全有效落地

用友BIP

信创 国产替代

APP流水线测试领域探索与最佳实践 | 京东物流技术团队

京东科技开发者

测试 app测试 app自动化测试 企业号 7 月 PK 榜

华为云GaussDB亮相2023可信数据库发展大会,荣获三项评测证书!

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

SpringIoc容器之Aware | 京东云技术团队

京东科技开发者

spring aware springloc Aware 接口 企业号 7 月 PK 榜

实例讲解看nsenter带你“上帝视角”看网络

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 7 月 PK 榜

云拨测全面升级丨单次拨测低至 0.001 元

阿里巴巴云原生

阿里云 云原生 可观测 云拨测

Kubernetes云原生实战:分布式GeaFlow实现图研发,构建第一个商业智能应用

TuGraphAnalytics

Kubernetes 云原生 k8s BI 商业智能

全新技术驱动预算管理全面升级

用友BIP

全面预算

基于STM32的300W无刷直流电机驱动方案

元器件秋姐

驱动 无刷电机 直流电机 SMT32 FOC

一辆没有“刹车”的跑车,你敢开多快?

原点安全

数据资产价值 数据安全管理 贴源保护

七月创作之星挑战赛开始咯~

Openlab_cosmoplat

开源 开源社区 创作活动

一文搞懂Git,掌握日常命令和基本操作

互联网工科生

git 知识

构建学生数据库

猫九

数据库·

从大数据到图计算-Graph On BigData

TuGraphAnalytics

GitHub 大数据 开源 图计算 GeaFlow

数智化底座正在成为当前竞争的焦点

用友BIP

数智底座

从混沌到秩序的蜕变,SRE解码云计算运维奥秘

鲸品堂

云计算 SRE SRE实践 企业号 7 月 PK 榜

掌握 Dubbo:入门教程

Apifox

程序员 gRPC dubbo RPC 开发

我感兴趣的技术四剑客 | 社区征文

法医

前端 年中技术盘点

使用第一性原理思维思考如何打造提高生产力的平台 | 京东云技术团队

京东科技开发者

数字化转型 平台工程 企业号 7 月 PK 榜

科兴未来|2023“直通乌镇” 全球互联网大赛

科兴未来News

CST电磁仿真软件配置的CPU、内存、显卡显存越大越好吗?

思茂信息

cst cst使用教程 cst操作 cst电磁仿真 cst仿真软件

Pytorch: autograd与逻辑回归的实现

timerring

人工智能

网易三个S级项目制作人,为什么选择在这个渠道“爆料”?

最新动态

谈谈分布式事务

Monin

分布式事务 微服务 云原生 事务 java 编程

论文解读|TuGraph Analytics 流式图计算论文入选国际顶会 SIGMOD

TuGraphAnalytics

大数据 论文 图计算 SIGMOD GeaFlow

如果我是一个小白,怎么开发网页

猫九

前端

谁在以太坊区块链上循环交易?GeaFlow+Kafka的0元流图解决方案

TuGraphAnalytics

区块链 以太坊 kafka 图计算 GeaFlow

Mybatis-SQL分析组件 | 京东云技术团队

京东科技开发者

mybatis sql mybatis入门 企业号 7 月 PK 榜

Node.js V0.12新特性之在单进程中跑多个实例_架构/框架_Ben Noordhuis_InfoQ精选文章