Javascript 从子进程执行node.js中的代码
我是node.js的新手,我正在尝试从一个模块的子进程中执行一些代码 让我解释一下,我的简单服务器在index.js中Javascript 从子进程执行node.js中的代码,javascript,node.js,firebase,firebase-realtime-database,Javascript,Node.js,Firebase,Firebase Realtime Database,我是node.js的新手,我正在尝试从一个模块的子进程中执行一些代码 让我解释一下,我的简单服务器在index.js中 var server = http.createServer(handleRequest); server.listen(PORT, function(){ console.log("Server listening on: http://localhost:%s", PORT); }); 获取url后,我将启动一个子进程: function handleReque
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
获取url后,我将启动一个子进程:
function handleRequest(req, res){
console.log('Request path = ' + req.url)
launchWorker(req.url)
res.end('Path Hit: ' + req.url);
}
// workers execution
function launchWorker(path) {
const worker = child_process.spawn('node', ['./worker.js', path.substring(1)])
worker.stdout.on('data', function(data) {
console.log('worker: ' + data.toString())
});
worker.stderr.on('data', function(data) {
console.log('stderr : ' + data)
});
worker.on('close', function(code, signal) {
console.log('child process exited with code: ' + code)
});
}
因此,我有一个worker.js文件来执行一些代码,我使用['./worker.js',path.substring(1)]
我使用firebase执行一些操作,因此在my worker.js中,我初始化了我的firebase管理员、凭据和数据库:
var admin = require("firebase-admin");
var serviceAccount = require("./service_account.json");
var defaultApp = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "http://myAdress.firebase"
});
var db = admin.database()
performWork()
function performWork() {
var arg = process.argv[2]
var ref = db.ref("something");
ref.once("value", function(snapshot) {
console.log(arg);
process.exit(1);
});
}
我将每分钟启动一个进程,所以我想做的是将firebase数据库作为参数提供给我的孩子,这样我就不会在每次启动进程时创建对firebase的访问。
这就是我在index.js中尝试做的:
var admin = require("firebase-admin");
var serviceAccount = require("./service_account.json");
var defaultApp = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "http://myAdress.firebase"
});
var db = admin.database()
我只是将数据库作为参数传递给我的工作人员。
然后在我的工人身上,我得到了fb:
function performWork() {
var arg = process.argv[2]
var db = process.argv[3]
var ref = db.ref("something");
ref.once("value", function(snapshot) {
console.log(arg);
process.exit(1);
});
}
但是当我到达一个url时,我得到一个错误:
TypeError: db.ref is not a function
at performWork (/home/user/worker.js:12:15)
at Object.<anonymous> (/home/user/worker.js:6:1)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
TypeError:db.ref不是函数
在performWork(/home/user/worker.js:12:15)
反对。(/home/user/worker.js:6:1)
在模块处编译(Module.js:635:30)
在Object.Module.\u extensions..js(Module.js:646:10)
在Module.load(Module.js:554:32)
在tryModuleLoad时(module.js:497:12)
在Function.Module.\u加载(Module.js:489:3)
位于Function.Module.runMain(Module.js:676:10)
启动时(bootstrap_node.js:187:16)
在bootstrap_node.js:608:3
我认为worker.js根本不了解firebase,无法访问函数.ref。即使db不是null(我可以打印它的值)
所以我的问题是,我需要在worker.js中导入/执行什么,这样它才能执行firebase模块中的代码?我试图要求用户。。。但是什么都没用。
我的问题也更一般,我想在另一个文件中编写一些帮助程序(创建、读取、删除),但我会遇到同样的问题。
谢谢你的帮助 不能将活动Javascript对象传递给另一个进程。如果对象仅包含Javascript数据,则可以使用JSON对其进行序列化,并将其传递给另一个进程,在该进程中,副本将被反序列化,但这对于具有本机代码或TCP连接的对象不起作用,后者很可能就是您的开放数据库句柄所表示的。在某些情况下,您可以将TCP连接传递给另一个进程(集群可以做到这一点),但如果您将它包装在另一个连接对象中(通常是这样),那么在另一个进程中用传递的TCP连接重新构建一个活动连接对象需要大量的工作。就我个人而言,我宁愿避免所有这些麻烦 除非您的子进程中正在进行大量CPU工作,否则我看不出有任何理由需要在这里使用子进程。当请求传入时,您可以在主进程中执行您想要的任何数据库工作。数据库工作应该主要是异步的,因此不应该明显地阻塞main node.js线程,您应该能够同时处理多个请求。对于大量请求,您的数据库将成为瓶颈,而不是主node.js进程 如果您有合理的理由使用子进程,并且不想为每个子进程打开和关闭新的DB连接,那么您可能希望创建一组工作进程,这些进程打开后保持打开状态。然后,他们可以打开自己与数据库的连接并保持其打开状态。当一个新的请求到达main node.js进程时,您可以使用某种形式的IPC(可能只是写入子进程的stdin)向它发送一个新的作业,它就在那里等待处理。您可以通过决定需要多少个工作进程来优化吞吐量来优化事情。然后,当一个新作业进入时,您只需将该作业放入队列中。如果有空闲工人,则将队列中的下一个作业发送给该工人。每次工作人员完成作业时,您都会检查队列中是否有其他项目要发送给该工作人员
这样做,您就不会一直创建和终止到数据库的新连接,每个工作进程都可以拥有并保持自己的数据库连接。为什么您认为有必要使用子进程?我看不到有任何迹象表明它们是必要的,并且使用子进程会带来不可忽略的性能损失。我需要使用子进程来释放内存,这是一项非常繁重的任务,调用次数超过了调用次数,这是我发现的在进程完成时真正释放内存的唯一方法。好吧,谢谢你的解释,是的,我有大量的进程要运行(每30秒一次、每分钟一次、每5次、每10次……)处理大量数据,我有16 gb ram,这是我找到的唯一释放内存的方法,当子进程结束时,一切都被释放,由于内存不足错误,我的服务器可以在不重新启动的情况下运行此进程一个月。谢谢
TypeError: db.ref is not a function
at performWork (/home/user/worker.js:12:15)
at Object.<anonymous> (/home/user/worker.js:6:1)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3