标签: node-cluster

使用多个服务器实例扩展 websockets/ws

我在单机上使用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)

websocket node.js pm2 node-cluster

6
推荐指数
1
解决办法
1万
查看次数

node.js + socket.io:拍卖网站开发

我目前正在使用 node.js 和 socket.io 处理拍卖脚本。但是站点是使用 PHP 和 MySQL 开发的。在这里,我仅将 node.js + socket.io 用于拍卖投标过程。在拍卖期间,该网站将有 500-1000 名登录用户查看单个页面。只有一件物品将在拍卖中,并且将在一天内出售一次。

我将向从服务器到客户端的所有用户广播(发射)一个倒数计时器。在服务器端,我将使用 setInterval(),1 秒的递归 setTimeout() 倒计时到拍卖结束时间。除此之外,唯一发送的其他消息将是从单个客户端传递到服务器然后向所有客户端广播的当前出价。这种方式做的靠谱吗?它是否能够处理服务器上的使用情况?在这里,我测试了 500 个用户意味着浏览器挂起计时器。

服务器.js

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)

javascript node.js socket.io node-redis node-cluster

5
推荐指数
1
解决办法
3460
查看次数

使用 websockets 的节点集群

我有一个节点集群,其中主节点响应 http 请求。服务器还侦听 websocket 连接(通过socket.io)。客户端通过所述 websocket 连接到服务器。现在客户端在各种游戏之间进行选择(每个节点进程处理一个游戏)。

我的问题如下:

  • 我应该为每个节点进程打开一个新连接吗?如何告诉客户端他应该连接到确切的节点进程 X?(因为服务器可能会在其打开时处理传入的连接请求)
  • 是否可以将套接字传递给节点进程,从而无需打开新连接?
  • 如果我只使用一个连接(在主进程中)并将用户消息传递给相应的节点进程并将进程消息返回给用户,有什么缺点?(感觉在进程间发送消息的时候,复制比较大的对象会消耗大量CPU)

sockets websocket node.js socket.io node-cluster

5
推荐指数
1
解决办法
3834
查看次数

100% CPU 使用率使用集群和 mariaSQL,当集群退出并重新启动时

在我的 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)

sockets node.js mariasql node-cluster

5
推荐指数
1
解决办法
441
查看次数

木偶-协议错误(Page.navigate):目标已关闭

如您在下面的示例代码中所看到的,我将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

5
推荐指数
5
解决办法
5819
查看次数

Node.js 集群共享缓存

我正在使用节点缓存来创建本地缓存,但是,我遇到的问题是,当将应用程序与创建应用程序集群的 PM2 一起使用时,缓存会被创建多次,每个进程一个 - 这并不算太多由于缓存的数据很小,因此内存不是问题,因此存在问题。

真正的问题是,我对应用程序进行了 API 调用来刷新缓存,但是当调用此 API 时,它只会刷新处理该调用的特定进程的缓存。

有没有办法通知所有工作人员执行某项功能?

我确实考虑过使用 Redis 来缓存,因为这样可以更简单地只拥有一个缓存,我使用 Redis 的问题是我不确定扩展它的最佳方法,我目前有 50 个应用程序,并且不会不想为每个应用程序设置一个新的 Redis 数据库,另一种方法是使用ioredis,它为每个应用程序提供透明的密钥前缀,但如果一个应用程序意外地从其他客户端应用程序读取数据,这可能会导致一些安全漏洞 -我不相信有一种方法可以删除特定前缀(即一个应用程序/客户端)的所有键,因为 FLUSHALL 将删除所有键

共享集群节点实例缓存的最佳实践是什么,但在应用程序也有许多实例的情况下 - 想想 SAAS 应用程序。

目前,我解决此问题的方法是使用 node-cron 每 15 分钟清除一次缓存,但是,缓存中的某些项目实际上永远不会更改,并且还有其他项目应该在外部工具后立即更新通过 API 调用向应用程序发出信号以刷新缓存

caching redis node.js pm2 node-cluster

5
推荐指数
1
解决办法
3044
查看次数

节点 cluster.isPrimary 未定义

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

5
推荐指数
2
解决办法
3198
查看次数

无法调试节点子进程(使用节点本机调试器)

我正在尝试使用本机节点调试器调试节点子进程.例如,请参阅此回购.

我尝试了所有选项之王,根据: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/...镀铬.调试主进程效果很好,我也看到了子进程输出.唯一不起作用的是子过程的调试...

我在这做错了什么?

javascript node.js node-debugger node-cluster

3
推荐指数
1
解决办法
1160
查看次数

节点集群有多个进程监听同一个端口

我在阅读有关 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.js node-cluster

3
推荐指数
1
解决办法
1617
查看次数

是否可以使用 Node 工作线程来执行数据库插入?

我最近阅读了 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

3
推荐指数
1
解决办法
2275
查看次数