写点什么

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:564772
用户头像

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

关注

评论

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

DevOps系列之从前线到后勤:制品管理的演变历史

嘉为蓝鲸

DevOps 制品库 制品管理

牛市来啦?交易量大涨!金融机构如何强化应急体系,筑牢运维安全防线?

嘉为蓝鲸

运维 可观测 应急响应 IT运维管理

Mint Blockchain:用 NFT 链接全球消费者的 Layer2 网络

NFT Research

NFT #Web3 L2

【DevOps系列】DevOps全过程质量管控

嘉为蓝鲸

DevOps 研发 质量管控

京东电商搜索:大模型生成式检索优化实践

京东零售技术

大模型

法国 mixtral一种具有开放权重的高质量稀疏专家混合模型

测吧(北京)科技有限公司

测试

QT软件外包开发流程

北京木奇移动技术有限公司

软件外包公司 QT外包开发 QT开发公司

OASA走进三未信安、奇安信和360,共建龙蜥安全生态

OpenAnolis小助手

操作系统 龙蜥安全联盟

35 位委员参会,龙蜥社区 11 月技术委员会会议圆满结束

OpenAnolis小助手

操作系统 龙蜥社区 龙蜥技术委员会

倒计时1天!龙蜥社区可信计算SIG MeetUp即将在北京召开

OpenAnolis小助手

操作系统 可信计算 龙蜥meetup

嘉为蓝鲸受邀参加信通院2024数字化转型发展大会,携手客户斩获多项荣誉!

嘉为蓝鲸

数字化 中国信通院 研运一体化

渠道伙伴业务系统上线!嘉为蓝鲸WeOps渠道战略重要里程碑

嘉为蓝鲸

#WeOps

云起无垠创始人参与模糊测试研究被网络安全四大顶级会议—NDSS2024收录

云起无垠

边缘计算+人工智能:让设备更聪明的秘密

天津汇柏科技有限公司

边缘计算 AI 人工智能

【DevOps系列】赋能开发:理解仓库代理的力量

嘉为蓝鲸

制品库管理 制品库 制品仓库 Packages

webGL开发框架及特点

北京木奇移动技术有限公司

软件外包公司 数字孪生开发 webgl开发

硬核、高能,龙蜥社区走进中科方德 MeetUp 圆满结束(附技术PPT下载)

OpenAnolis小助手

操作系统 龙蜥社区 龙蜥meetup

【DevOps系列】制品库在行动:本地管理与多地同步的实战应用

嘉为蓝鲸

制品库 制品管理

如何设置AD域用户仅登录到指定的计算机?AD域管理软件

运维有小邓

AD域 IT自动化运维 AD域管理

「百度集团」资深副总裁、原IDG负责人李震宇加入“华为系”具身智能赛道初创公司!

机器人头条

自动驾驶 华为 人形机器人 具身智能

《Django 5 By Example》阅读笔记:p493-p520

codists

Python django

淘宝电商API全解析:赋能商家,驱动电商新生态

代码忍者

API 接口 pinduoduo API

【DevOps系列】升级你的制品:探讨制品晋级的战略

嘉为蓝鲸

制品管理 制品仓库 制品仓库 Packages

DocFlow票据AI自动化处理工具:出色的文档解析+抽取能力,提升企业文档数字化管理效能

合合技术团队

人工智能 数字化 文档解析 票据

文献解读-Processing UMI Datasets at High Accuracy and Efficiency with the Sentieon ctDNA Analysis Pipeline

INSVAST

基因测序 液体活检 生信分析 Sentieon 变异检测

产品经理如何进行竞品分析

易成研发中心

产品经理 竞品分析

开源进校园,开放原子校源行 Meetup(中南大学站)圆满结束

OpenAnolis小助手

操作系统 龙蜥高校行

稳!Zilliz助力XTransfer基于RAG打造B2B外贸金融加速器

Zilliz

Milvus zilliz cloud 大模型应用 企业知识库

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