【问题标题】:Node.js cluster errorNode.js 集群错误
【发布时间】:2017-10-02 07:15:46
【问题描述】:

您好,我对 node.js 和 javascript 非常陌生,我正在尝试使用 nodejs 集群模块创建一个 culster.js,在我的 if 语句结束时,我正在调用 server.js 来启动应用程序。

cluster.js

const cluster = require('cluster');
const cpuCount = require('os').cpus().length;
const startServer = require('./server');

if (cluster.isMaster) {
  for (let i = 0; i < cpuCount; i += 1) {
    cluster.fork();
  }
  cluster.on('exit', () => {
    cluster.fork();
  });
} else {
  return startServer;
}

server.js

const fs = require('fs');
const path = require('path');

const express = require('express');
const auth = require('http-auth');
const {
  createBundleRenderer,
} = require('vue-server-renderer');

const bundle = fs.readFileSync('dist/server.js', 'utf-8');
const renderer = createBundleRenderer(bundle);

function parseIndexHtml() {
  const [
    entire,
    htmlOpen,
    htmlOpenTailAndHead,
    headCloseAndBodyOpen,
    bodyOpenTailAndContentBeforeApp,
    contentAfterAppAndHtmlClose,
  ] = fs.readFileSync('index.html', 'utf8').match(/^([\s\S]+?<html)([\s\S]+?)(<\/head>[\s\S]*?<body)([\s\S]+?)<div id="?app"?><\/div>([\s\S]+)$/);

  return {
    entire,
    htmlOpen,
    htmlOpenTailAndHead,
    headCloseAndBodyOpen,
    bodyOpenTailAndContentBeforeApp,
    contentAfterAppAndHtmlClose,
  };
}

const indexHtml = parseIndexHtml();
const app = express();

const basicAuth = auth.basic({
  realm: 'Jobportal',
}, (username, password, callback) => {
  callback(username === 'x' && password === 'x');
});

app.get('/ping', (request, response) => {
  response.status(200).end();
});

app.use(auth.connect(basicAuth));

// serve pure static assets
app.use('/public', express.static(path.resolve('./public')));
app.use('/dist', express.static(path.resolve('./dist')));

app.get('*', (request, response) => {
  const context = {
    url: request.url,
  };

  renderer.renderToString(context, (error, html) => {
    if (error) {
      if (error.code === '404') {
        response.status(404).end(indexHtml.entire);
      } else {
        response.status(500).end(indexHtml.entire);
        console.error(`Error during render: ${request.url}`); // eslint-disable-line
        console.error(error); // eslint-disable-line
      }
      return;
    }

    const {
      title,
      htmlAttrs,
      bodyAttrs,
      link,
      style,
      script,
      noscript,
      meta,
    } = context.meta.inject();

    response.write(
      `${indexHtml.htmlOpen} data-vue-meta-server-rendered ${htmlAttrs.text()} ${indexHtml.htmlOpenTailAndHead}
      ${meta.text()}
      ${title.text()}
      ${link.text()}
      ${style.text()}
      ${script.text()}
      <script>
        window.__INITIAL_STATE__ = ${JSON.stringify(context.initialState)}
      </script>
      ${noscript.text()}
      ${indexHtml.headCloseAndBodyOpen} ${bodyAttrs.text()} ${indexHtml.bodyOpenTailAndContentBeforeApp}
      ${html}
      <script src="/dist/client.js"></script>
      ${indexHtml.contentAfterAppAndHtmlClose}`
    );

    response.end();
  });
});

const port = 8181;

// start server
app.listen(port, () => {
  console.log(`server started at port ${port}`); // eslint-disable-line
});

我收到一个错误

server started at port 8181
events.js:163
      throw er; // Unhandled 'error' event
      ^

Error: bind EADDRINUSE null:8181
    at Object.exports._errnoException (util.js:1050:11)
    at exports._exceptionWithHostPort (util.js:1073:20)
    at listenOnMasterHandle (net.js:1336:16)
    at rr (internal/cluster/child.js:111:12)
    at Worker.send (internal/cluster/child.js:78:7)
    at process.onInternalMessage (internal/cluster/utils.js:42:8)
    at emitTwo (events.js:111:20)
    at process.emit (events.js:194:7)
    at process.nextTick (internal/child_process.js:766:12)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
events.js:163
      throw er; // Unhandled 'error' event
      ^

有什么想法吗?

【问题讨论】:

  • 您应该发布您的startServer 代码。查看错误,您可能需要明确设置服务器的 IP 地址或主机名。
  • @Sebastian-LaurenţiuPlesciuc 我已经添加了代码。谢谢
  • 您需要验证该端口是否已被您的系统占用。
  • @KingReload 它没有被占用,我什至将其更改为 8080 仍然得到相同的错误。这是以前的工作,我的旧代码是这样的:var cluster = require('cluster'); if (cluster.isMaster) { // Count the machine's CPUs var cpuCount = require('os').cpus().length; // Create a worker for each CPU for (var i = 0; i &lt; cpuCount; i += 1) { cluster.fork(); } // Listen for dying workers cluster.on('exit', function () { cluster.fork(); }); } else { require('./server'); }
  • @Momo 我已经发布了一个答案来测试端口是否被占用

标签: javascript node.js express node-cluster


【解决方案1】:

EADDRINUSE 表示listen() 尝试绑定服务器的端口号已被使用。

您需要验证该端口是否已在您的系统上使用。为此:

  • 在 linux 上:sudo netstat -nltp | grep (port) 在您的情况下是端口 8181。
  • 在 OSX 上:sudo lsof -i -P | grep (port)

如果有结果,需要kill过程(kill &lt;pid&gt;)。

您应该检查 pm2 list 是否返回 0 进程。此外,当您执行pm2 stopAll 时,不会释放套接字。不要忘记执行pm2 kill 以确保守护进程被杀死。

$ pm2 kill
Daemon killed

验证 Windows:

C:\> netstat -a -b
  • a 显示所有连接和监听端口。

  • b 显示创建每个连接或侦听端口所涉及的可执行文件。在某些情况下,众所周知的可执行文件包含多个独立的组件,在这些情况下,会显示创建连接或侦听端口所涉及的组件序列。在这种情况下,可执行文件名称在底部的 [] 中,顶部是它调用的组件,依此类推,直到到达 TCP/IP。请注意,此选项可能会很耗时并且会失败,除非您拥有足够的权限。

  • n 以数字形式显示地址和端口号。

  • o 显示与每个连接关联的拥有进程 ID。

在 windows 命令行中杀死的示例:

如果您知道要杀死的进程的名称,对于 examplenotepad.exe,请在命令提示符下使用以下命令来结束它:

taskkill /IM notepad.exe

要终止进程的单个实例,请指定其进程 ID (PID)。对于example,如果所需进程的PID为827,使用以下命令杀死它:

taskkill /PID 827

【讨论】:

  • 感谢您的帮助,我已经尝试过了,并且该端口可以免费使用我没有得到任何答复。
  • @Momo note server started at port 8181 在您的控制台中,表示它已经连接,但之后您尝试再次连接
  • 正确!我想这与我的 if 语句有关!
  • 希望对您有所帮助 ;) 如果您再次遇到EADDRINUSE,这意味着服务器尝试连接到同一地址/端口两次
  • 感谢您的帮助。我仍然无法解决我的问题:) 使用 cluster.js 中的代码
猜你喜欢
  • 2012-11-22
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多