简体   繁体   English

Node.js 集群错误

[英]Node.js cluster error

Hello i am very new to node.js and javascript, i am trying to create a culster.js with the nodejs cluster module, at the end of my if statement i am calling server.js to start the app.您好,我是 node.js 和 javascript 的新手,我正在尝试使用 nodejs 集群模块创建一个 culster.js,在我的 if 语句末尾我调用 server.js 来启动应用程序。

cluster.js集群.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服务器.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
});

I get an error我收到一个错误

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
      ^

Any ideas why ?任何想法为什么?

EADDRINUSE means that the port number which listen() tries to bind the server to is already in use. EADDRINUSE表示listen()尝试将服务器绑定到的端口号已在使用中。

You need to verify if the port is already taken on your system. 您需要验证系统上是否已使用该端口。 To do that: 要做到这一点:

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

If you have a result, you need to kill the process ( kill <pid> ). 如果有结果,则需要kill该进程( kill <pid> )。

You should check if pm2 list returns 0 process. 您应该检查pm2 list返回0进程。 In addition, when you do a pm2 stopAll , the socket is not released. 另外,当您执行pm2 stopAll ,不会释放套接字。 Don't forget to do a pm2 kill to be sure the daemon is killed. 不要忘记执行pm2 kill ,以确保守护程序被杀死。

$ pm2 kill
Daemon killed

Verifying for Windows: 验证Windows:

C:\> netstat -a -b
  • a Displays all connections and listening ports. a显示所有连接和监听端口。

  • b Displays the executable involved in creating each connection or listening port. b显示创建每个连接或侦听端口所涉及的可执行文件。 In some cases well-known executables host multiple independent components, and in these cases the sequence of components involved in creating the connection or listening port is displayed. 在某些情况下,众所周知的可执行文件包含多个独立的组件,在这些情况下,将显示创建连接或侦听端口所涉及的组件顺序。 In this case the executable name is in [] at the bottom, on top is the component it called, and so forth until TCP/IP was reached. 在这种情况下,可执行文件的名称在底部的[]中,在顶部是其调用的组件,依此类推,直到达到TCP / IP。 Note that this option can be time-consuming and will fail unless you have sufficient permissions. 请注意,此选项可能很耗时,除非您拥有足够的权限,否则它将失败。

  • n Displays addresses and port numbers in numerical form. n以数字形式显示地址和端口号。

  • o Displays the owning process ID associated with each connection. o显示与每个连接关联的拥有进程ID。

EXAMPLES to kill in windows command line: 在Windows命令行中杀死的示例:

If you know the name of a process to kill, for example notepad.exe, use the following command from a command prompt to end it: 如果您知道要杀死的进程的名称, example notepad.exe,请在命令提示符处使用以下命令将其终止:

taskkill /IM notepad.exe

To kill a single instance of a process, specify its process id (PID). 要终止某个进程的单个实例,请指定其进程ID(PID)。 For example , if the desired process has a PID of 827, use the following command to kill it: example ,如果所需进程的PID为827,请使用以下命令将其终止:

taskkill /PID 827
const throng = require('throng');

throng({
  master: () => {
    console.log('Started master');
  },
  start: (id) => {
    console.log(`Started worker ${id}`);
    require('./server');

    process.on('SIGTERM', () => {
      console.log(`Worker ${id} exiting...`);
      process.exit();
    });
  },
});

I had to add "throng" package https://www.npmjs.com/package/throng And follow the latest rules from http://eslint.org/docs/rules/ 我必须添加“ throng”包https://www.npmjs.com/package/throng并遵循http://eslint.org/docs/rules/中的最新规则

It works for me now 现在对我有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM