簡體   English   中英

Node.js 集群錯誤

[英]Node.js cluster error

您好,我是 node.js 和 javascript 的新手,我正在嘗試使用 nodejs 集群模塊創建一個 culster.js,在我的 if 語句末尾我調用 server.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;
}

服務器.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
      ^

任何想法為什么?

EADDRINUSE表示listen()嘗試將服務器綁定到的端口號已在使用中。

您需要驗證系統上是否已使用該端口。 要做到這一點:

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

如果有結果,則需要kill該進程( kill <pid> )。

您應該檢查pm2 list返回0進程。 另外,當您執行pm2 stopAll ,不會釋放套接字。 不要忘記執行pm2 kill ,以確保守護程序被殺死。

$ pm2 kill
Daemon killed

驗證Windows:

C:\> netstat -a -b
  • a顯示所有連接和監聽端口。

  • b顯示創建每個連接或偵聽端口所涉及的可執行文件。 在某些情況下,眾所周知的可執行文件包含多個獨立的組件,在這些情況下,將顯示創建連接或偵聽端口所涉及的組件順序。 在這種情況下,可執行文件的名稱在底部的[]中,在頂部是其調用的組件,依此類推,直到達到TCP / IP。 請注意,此選項可能很耗時,除非您擁有足夠的權限,否則它將失敗。

  • n以數字形式顯示地址和端口號。

  • o顯示與每個連接關聯的擁有進程ID。

在Windows命令行中殺死的示例:

如果您知道要殺死的進程的名稱, example notepad.exe,請在命令提示符處使用以下命令將其終止:

taskkill /IM notepad.exe

要終止某個進程的單個實例,請指定其進程ID(PID)。 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();
    });
  },
});

我必須添加“ throng”包https://www.npmjs.com/package/throng並遵循http://eslint.org/docs/rules/中的最新規則

現在對我有用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM