一、njs 全局对象核心定位
njs 对象是 NJS 运行时的"系统面板",无需导入、全局可用,所有 API 均围绕当前 VM 实例展开:
- 基础能力:查询版本信息,适配不同 NJS 版本的兼容性逻辑;
- 调试能力:格式化输出数据,快速定位代码问题;
- 监控能力:获取内存使用状态,排查内存泄漏;
- 生命周期管控:监听 VM 退出事件,执行资源清理操作。
二、核心 API 详解与实战示例
2.1 版本信息:njs.version & njs.version_number
版本信息是兼容性适配的核心依据,两个属性分别以字符串和数值形式返回 NJS 版本,满足不同场景的判断需求。
2.1.1 API 说明
| 属性 | 类型 | 说明 | 示例(以 0.7.4 为例) |
|---|---|---|---|
njs.version |
字符串 | 人类可读的版本号 | "0.7.4" |
njs.version_number |
数值 | 十六进制版本编码(主.次.修 = 0x00 07 04) | 0x000704(自 0.7.4 支持) |
2.1.2 实战:版本兼容性判断
在 NJS 脚本中,不同版本可能存在 API 差异(如 crypto 全局对象自 0.7.0 才支持),可通过版本判断实现兼容逻辑:
javascript
// 检查 NJS 版本是否 >= 0.7.0
function checkNjsVersion() {
// 解析版本号为数值(兼容 0.7.4 以下无 version_number 的场景)
const version = njs.version.split('.').map(Number);
const main = version[0], minor = version[1];
if (main > 0 || (main === 0 && minor >= 7)) {
console.log(`NJS 版本 ${njs.version} 符合要求,支持 crypto 全局对象`);
return true;
} else {
console.log(`NJS 版本 ${njs.version} 过低,请升级至 0.7.0+`);
return false;
}
}
// 0.7.4+ 可直接用 version_number 判断
if (njs.version_number && njs.version_number >= 0x000700) {
console.log("NJS 版本 ≥ 0.7.0,启用新特性");
}
2.2 数据调试:njs.dump()
njs.dump(value) 是 NJS 内置的"格式化打印工具",能将任意类型的值(对象、数组、字符串等)转换为易读的字符串,解决原生 console.log 输出复杂数据不清晰的问题。
2.2.1 API 说明
- 参数:
value- 任意类型的变量(对象、数组、基本类型均可); - 返回值:格式化后的字符串,保留数据结构(如对象的键值对、数组的索引)。
2.2.2 实战:调试复杂数据结构
在 NGINX 配置中调试请求头、响应体等复杂数据时,njs.dump() 能清晰展示数据结构:
javascript
function debugRequest(r) {
// 格式化输出请求头对象
const headersStr = njs.dump(r.headersIn);
// 格式化输出嵌套数组/对象
const complexData = {
name: "njs-demo",
version: njs.version,
features: ["crypto", "regex", "stream"],
memory: njs.memoryStats
};
const dataStr = njs.dump(complexData);
console.log("请求头信息:\n", headersStr);
console.log("自定义数据:\n", dataStr);
// 输出示例(格式化后):
// {
// "host": "example.com",
// "user-agent": "Mozilla/5.0",
// "accept": "*/*"
// }
}
2.3 内存监控:njs.memoryStats
njs.memoryStats(自 0.7.8 支持)是内存监控的核心属性,返回当前 VM 实例的内存使用统计,帮助排查 NJS 脚本的内存泄漏问题。
2.3.1 API 说明
njs.memoryStats 是一个对象,核心字段:
size:NJS 内存池从操作系统申请的内存字节数(反映当前 VM 占用的物理内存)。
2.3.2 实战:监控内存使用
在 NGINX 中定时输出内存状态,或在关键操作前后对比内存变化,排查异常占用:
javascript
function monitorMemory() {
if (!njs.memoryStats) {
console.log("当前 NJS 版本不支持 memoryStats(需 ≥ 0.7.8)");
return;
}
// 转换为 MB 便于阅读
const memoryMB = (njs.memoryStats.size / 1024 / 1024).toFixed(2);
console.log(`当前 NJS VM 内存占用:${memoryMB} MB`);
// 示例:记录操作前后内存变化
const before = njs.memoryStats.size;
// 模拟大数组操作
const largeArray = new Array(1000000).fill("test");
const after = njs.memoryStats.size;
console.log(`大数组操作后内存变化:${(after - before)/1024} KB`);
}
2.4 生命周期管控:njs.on()
njs.on(event, callback) 用于监听 VM 实例的生命周期事件,目前仅支持 exit 事件(自 0.5.2 支持),可在 VM 销毁前执行资源清理、日志记录等操作。
2.4.1 API 说明
- 参数1:
event- 事件名称,仅支持"exit"; - 参数2:
callback- 回调函数(无参数),VM 销毁前触发。
2.4.2 实战:VM 退出前的资源清理
在 NJS 脚本中,若存在临时文件、网络连接、定时器等资源,可通过 exit 事件确保销毁前释放:
javascript
// 模拟定时器资源
const timer = setInterval(() => {
console.log("定时任务执行中...");
}, 1000);
// 监听 VM 退出事件,清理资源
njs.on('exit', () => {
console.log("NJS VM 即将销毁,执行清理操作");
// 清除定时器
clearInterval(timer);
// 记录退出日志
console.log(`VM 退出 - 版本:${njs.version},最终内存占用:${(njs.memoryStats?.size/1024/1024).toFixed(2)} MB`);
});
三、完整实战:NJS 运行时监控脚本
结合上述 API,编写一个完整的 NJS 脚本,集成版本检查、内存监控、退出清理能力,并在 NGINX 中启用:
3.1 NJS 脚本(runtime-monitor.js)
javascript
// 全局初始化:版本检查
(function init() {
console.log("=== NJS 运行时初始化 ===");
const isSupported = checkNjsVersion();
if (!isSupported) {
console.error("初始化失败:版本不兼容");
return;
}
// 启动内存监控
setInterval(monitorMemory, 5000); // 每5秒输出一次内存
})();
// 版本检查函数
function checkNjsVersion() {
if (njs.version_number) {
const minVersion = 0x000708; // 要求 ≥ 0.7.8(支持 memoryStats)
if (njs.version_number < minVersion) {
console.log(`NJS 版本 ${njs.version} < 0.7.8,部分监控功能不可用`);
return true; // 降级兼容
}
}
console.log(`NJS 版本:${njs.version} (数值编码:0x${njs.version_number?.toString(16) || '000000'})`);
return true;
}
// 内存监控函数
function monitorMemory() {
if (!njs.memoryStats) return;
const memoryMB = (njs.memoryStats.size / 1024 / 1024).toFixed(2);
console.log(`[内存监控] 占用:${memoryMB} MB`);
}
// 监听 VM 退出
njs.on('exit', () => {
console.log("=== NJS VM 退出 ===");
const finalStats = njs.memoryStats ? `内存:${(njs.memoryStats.size/1024/1024).toFixed(2)} MB` : "无内存数据";
console.log(`最终状态 - 版本:${njs.version},${finalStats}`);
});
// NGINX 访问日志处理示例
function accessLogHandler(r) {
// 格式化输出请求信息
const reqInfo = {
method: r.method,
uri: r.uri,
remoteAddr: r.remoteAddress,
time: new Date().toISOString()
};
console.log("请求详情:", njs.dump(reqInfo));
r.return(200, `NJS Runtime Info: Version ${njs.version}`);
}
// 导出供 NGINX 调用的函数
export default { accessLogHandler };
3.2 NGINX 配置(nginx.conf)
nginx
http {
# 导入 NJS 脚本
js_import runtime from runtime-monitor.js;
server {
listen 80;
server_name localhost;
# 访问 /runtime 触发监控脚本
location /runtime {
js_content runtime.accessLogHandler;
}
}
}
四、使用注意事项
- 版本兼容性 :
njs.version_number仅 0.7.4+ 支持,低版本需通过解析njs.version字符串实现版本判断;njs.memoryStats仅 0.7.8+ 支持,低版本调用会返回undefined,需提前判断。
- 内存监控限制 :
njs.memoryStats.size是 VM 从系统申请的总内存,并非脚本实际使用的内存,仅作参考;- 避免高频调用
memoryStats,防止监控本身占用过多资源。
- exit 事件触发时机 :
exit事件在 VM 销毁前触发(如 NGINX 重启、配置重载、worker 进程退出),仅执行一次;- 回调函数中避免耗时操作,否则可能阻塞 VM 销毁。
五、总结
njs全局对象是管控 NJS 运行时的核心入口,version/version_number用于版本兼容,dump()用于调试,memoryStats用于监控,on('exit')用于生命周期管控;- 版本判断是适配不同 NJS 环境的基础,
dump()是调试复杂数据的高效工具,memoryStats可辅助排查内存问题; - 结合 NGINX 配置使用时,需注意 API 的版本支持范围,避免因版本过低导致脚本报错。