我在单机上使用websockets/ws 。它工作正常。我想在多核和多个实例上水平扩展它。对于多核,我尝试使用pm2,它似乎工作得很好。
第一个问题:这是最好的方法还是合适的方法?这是我使用 pm2 的测试代码
// ws-server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3131 });
var pid = process.pid + ''
console.log('process pid: '+ pid)
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
if (message === 'get-pid') {
ws.send('pid-' + pid)
} else {
var matched = pid === message ? 'old friends' : 'strangers'
ws.send([pid, message, 'we are ' + matched].join(', '))
}
});
ws.send('first time')
});
Run Code Online (Sandbox Code Playgroud)
和客户端 websocket 实例
// …Run Code Online (Sandbox Code Playgroud) 我目前正在使用 node.js 和 socket.io 处理拍卖脚本。但是站点是使用 PHP 和 MySQL 开发的。在这里,我仅将 node.js + socket.io 用于拍卖投标过程。在拍卖期间,该网站将有 500-1000 名登录用户查看单个页面。只有一件物品将在拍卖中,并且将在一天内出售一次。
我将向从服务器到客户端的所有用户广播(发射)一个倒数计时器。在服务器端,我将使用 setInterval(),1 秒的递归 setTimeout() 倒计时到拍卖结束时间。除此之外,唯一发送的其他消息将是从单个客户端传递到服务器然后向所有客户端广播的当前出价。这种方式做的靠谱吗?它是否能够处理服务器上的使用情况?在这里,我测试了 500 个用户意味着浏览器挂起计时器。
var cluster = require('cluster');
var app = require('express')();
//var http = require('http');
var https = require('https');
var socket = require('socket.io');
var redis = require('redis');
var redisAdapter = require('socket.io-redis');
var request = require('request');
var fs = require('fs');
var options = {
key: fs.readFileSync('keys/e1317_0f2c9_71565598d419e37e376ccef5c2827113.key'),
cert: fs.readFileSync('certs/e1317_0f2c9_1468152279_2dc46c1f2cc135a.crt'),
ca: fs.readFileSync('cabundles/90490a5c829d2aca24f22b5820864c6e_1935558000.cabundle')
};
//var server = http.createServer( app );
var server = https.createServer(options, …Run Code Online (Sandbox Code Playgroud) 我有一个节点集群,其中主节点响应 http 请求。服务器还侦听 websocket 连接(通过socket.io)。客户端通过所述 websocket 连接到服务器。现在客户端在各种游戏之间进行选择(每个节点进程处理一个游戏)。
我的问题如下:
在我的 Node.JS 应用程序中,我使用集群来利用我的多核 CPU。我正在使用节点的 mariasql 库与我的数据库进行通信。由于node-mariasql库不支持池化,我使用第三方 - generic-pool来维护连接池。
我注意到,每当主线程中的连接在未捕获的异常导致其中一个子集群重新启动后关闭时,我们的 CPU 使用率就会上升到 100%。
每当子集群重新启动时,我都会破坏所有 MySQL 连接。
节点版本 - v4.2.2
MariaDB 版本 - v10.0.15
node-mariasql 版本 - v0.2.5
可重现的代码 - https://github.com/bsurendrakumar/node-simplex/
var pool = poolModule.Pool({
name: 'mariadb',
create: function(callback) {
var client = new mSQLClient();
client.connect(dbConfig);
client.on('error', function(err) {
callback(err, null);
});
client.on('ready', function() {
callback(null, client);
});
},
destroy: function(client) {
if(cluster.isMaster) {
console.log('Destroying / ending master thread ID -', client.threadId);
}
if(isDraining) {
client.destroy();
} …Run Code Online (Sandbox Code Playgroud) 如您在下面的示例代码中所看到的,我将Puppeteer与Node中的一组工作人员一起使用,以通过给定的URL运行多个网站截图请求:
const cluster = require('cluster');
const express = require('express');
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');
async function getScreenshot(domain) {
let screenshot;
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] });
const page = await browser.newPage();
try {
await page.goto('http://' + domain + '/', { timeout: 60000, waitUntil: 'networkidle2' });
} catch (error) {
try {
await page.goto('http://' + domain + '/', { timeout: 120000, waitUntil: 'networkidle2' });
screenshot = await page.screenshot({ type: 'png', encoding: 'base64' });
} …Run Code Online (Sandbox Code Playgroud) node.js web-scraping node-cluster google-chrome-headless puppeteer
我正在使用节点缓存来创建本地缓存,但是,我遇到的问题是,当将应用程序与创建应用程序集群的 PM2 一起使用时,缓存会被创建多次,每个进程一个 - 这并不算太多由于缓存的数据很小,因此内存不是问题,因此存在问题。
真正的问题是,我对应用程序进行了 API 调用来刷新缓存,但是当调用此 API 时,它只会刷新处理该调用的特定进程的缓存。
有没有办法通知所有工作人员执行某项功能?
我确实考虑过使用 Redis 来缓存,因为这样可以更简单地只拥有一个缓存,我使用 Redis 的问题是我不确定扩展它的最佳方法,我目前有 50 个应用程序,并且不会不想为每个应用程序设置一个新的 Redis 数据库,另一种方法是使用ioredis,它为每个应用程序提供透明的密钥前缀,但如果一个应用程序意外地从其他客户端应用程序读取数据,这可能会导致一些安全漏洞 -我不相信有一种方法可以删除特定前缀(即一个应用程序/客户端)的所有键,因为 FLUSHALL 将删除所有键
共享集群节点实例缓存的最佳实践是什么,但在应用程序也有许多实例的情况下 - 想想 SAAS 应用程序。
目前,我解决此问题的方法是使用 node-cron 每 15 分钟清除一次缓存,但是,缓存中的某些项目实际上永远不会更改,并且还有其他项目应该在外部工具后立即更新通过 API 调用向应用程序发出信号以刷新缓存
Node 说它cluster.isMaster已被弃用,我们应该使用cluster.isPrimary. 但是,虽然isMaster毫无问题地返回我 true,但当我undefined尝试时我得到cluster.isPrimary:
const cluster = require("cluster");
console.log(cluster.isPrimary); /// undefined
console.log(cluster.isMaster); /// true
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
multithreading cluster-computing child-process node.js node-cluster
我正在尝试使用本机节点调试器调试节点子进程.例如,请参阅此回购.
我尝试了所有选项之王,根据:debug1,debug1,debug3(以及我在网上找到的很多其他参考资料).
没有那些选项对我有用..
这是我的示例代码:
index.js:
const spawn = require('child_process').spawn;
const path = require('path');
const ls = spawn('node', [path.resolve('./child.js')], {execArgv: '--debug-brk=4545'});
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Run Code Online (Sandbox Code Playgroud)
child.js:
debugger;
const a = 123;
console.log(a);
Run Code Online (Sandbox Code Playgroud)
然后我跑:
node --debug-brk --inspect=9222 index.js
我打开chrome-devtools://devtools/...镀铬.调试主进程效果很好,我也看到了子进程输出.唯一不起作用的是子过程的调试...
我在这做错了什么?
我在阅读有关 Node js 中的集群的内容时遇到了一个简单的示例,而主文件创建了四个子进程,每个进程都监听 8080 端口。
代码运行良好,但我不明白:
如何让多个子进程监听同一个端口?
我期待收到这样的消息
错误:监听 EADDRINUSE:地址已在使用中 :::8080
const cluster = require("cluster");
if (cluster.isMaster) {
for (let i = 0; i <= 4; i++) cluster.fork();
} else {
require("./test.js");
}
Run Code Online (Sandbox Code Playgroud)
测试.js
const http1 = require("http");
http1
.createServer((req, res) => {
console.log("request1");
res.write("hello1");
res.end();
})
.listen(8080, () => {
console.log("begin");
});
Run Code Online (Sandbox Code Playgroud) 我最近阅读了 Node 的“worker_threads”模块,该模块允许在多个线程中并行执行 Javascript 代码,这对于 CPU 密集型操作非常有用。(注意:这些不是 Chrome 在浏览器中制作的网络工作者)
我正在构建一个功能,我需要在不阻止浏览器的情况下执行大量 Postgres INSERT。
问题是:在我实例化 worker 的 Javascript 文件中,我不允许导入任何内容,包括本机 Node 模块或 NPM 库,如执行数据库查询所必需的 Knex.js。我收到一条错误消息:文件一执行,就不能在模块外使用 import 语句。
我试过将工作代码放在另一个文件中,顶部有一个导入语句(同样的错误)。我尝试将 Knex 对象提供给 workerData,但它无法克隆非本地 JS 对象。
我没有想法 - 如果我们不能导入任何 NPM 库,有没有人知道如何在工作线程中与数据库交互?!?!
// mainThread.js
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
import knex from 'knex'; // --> *** UNCAUGHT EXCEPTION: Cannot use import statement outside a module ***
if (isMainThread) {
module.exports = async function runWorker (rowsToInsert = []) {
return new …Run Code Online (Sandbox Code Playgroud) worker-thread node.js import-module node-cluster node-worker-threads
node-cluster ×10
node.js ×10
javascript ×2
pm2 ×2
socket.io ×2
sockets ×2
websocket ×2
caching ×1
mariasql ×1
node-redis ×1
puppeteer ×1
redis ×1
web-scraping ×1