本文介绍了具有多个请求的Express.js(Node.js)中的ECONNRESET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定标准的Express.js设置

  const express = require('express'); 
const app = express();
const router = express.Router();

router.get('/ test /:id',(req,res)=> {
返回res.status(200).json({hello:'world'} );
});

app.use('/ api',router);

app.listen(3000,()=> console.info('Up on port 3000));

我在端点上再次发出1000个请求,一个接一个:

  const fetch = require('node-fetch'); 
for(let i = 0; i< 1000; i ++){
let id = Math.floor(Math.random()* 12)+ 1;
fetch(`http:// localhost:3000 / api / test / $ {id}`)。然后(res => res.json())。then(data => console.log(data) ))。catch(error => console.error(error));
}

我确实看到了返回的数据,但我偶尔会看到一个 ECONNRESET 错误。 ECONNRESET 错误消息的数量也各不相同:有时我得到一些,有时甚至更多。我确实理解了这个消息,但我无法解决它背后的问题。



这是一个示例错误:

  {FetchError:对http:// localhost:3000 / api / test / 8的请求失败,原因:在ClientRequest上连接ECONNRESET 127.0.0.1:3000 
。 <匿名> (node_modules / node-fetch / lib / index.js:1345:11)ClientRequest.emit的
(events.js:182:13)Socket.socketErrorListener的
(_http_client.js:399:9 )
在Socket.emit(events.js:182:13)
在emitErrorNT(internal / streams / destroy.js:82:8)
在emitErrorAndCloseNT(internal / streams / destroy。 js:50:3)
at process.internalTickCallback(internal / process / next_tick.js:72:19)
message:
'对http:// localhost:3000 / api /的请求部门/ 8失败,原因:连接ECONNRESET 127.0.0.1:3000',
类型:'系统',
错误:'ECONNRESET',
代码:'ECONNRESET'}

请注意,我曾尝试使用axios发出请求,内置的HTTP模块都可以使用。我确定问题出在我的Express应用程序处理请求但不确定如何正确修复它。



更新1:



根据评论中的建议,这里是异步版本:

  async function f(){
const array = Array.from(Array(1000).keys());
for(const el of array){
try {
let id = Math.floor(Math.random()* 12)+ 1;
const result = await fetch(`http:// localhost:3000 / api / test / $ {id}`)。then(res => res.json());
console.log(result);
返回结果;
} catch(e){
console.log(e);
}
}
}

f();

现在我偶尔会收到 ECONNREFUSED 消息。



更新2:



基于Mazki516的答案,这里的解决方案有效:

  //以前的需要语句
const cluster = require('cluster');
const os = require('os');

if(cluster.isMaster){
const cpuCount = os.cpus()。length
for(let i = 0; i< cpuCount; i ++){
cluster.fork()
}
} else {
const app = express();
//路线定义的其余部分
//也是app.listen()等...
}
cluster.on('exit',worker => {
console.log(`$ {worker.id} removed`);
cluster.fork();
});


解决方案

你看到这个的原因之一是因为你做的并行中的呼叫。
您可以一个接一个地启动调用,但循环可能会在服务器返回的第一个结果之前结束。
循环一直持续到结束,使调用堆栈充满了1000个异步请求到服务器。



你的硬件/软件限制没什么代码错了。
如果你想构建一个可以同时处理1k(以及更多)请求的服务器,我会查看节点的cluster模块。





但您可以随时将服务器扩展到一台计算机之外并处理更多流量。


Given a standard Express.js setup

const express = require('express');
const app = express();
const router = express.Router();

router.get('/test/:id', (req, res) => {
  return res.status(200).json({ hello: 'world' });
});

app.use('/api', router);

app.listen(3000, () => console.info('Up on port 3000));

I am making 1000 requests agains the endpoint, one after the other:

const fetch = require('node-fetch');
for (let i = 0; i < 1000; i++) {
  let id = Math.floor(Math.random() * 12) + 1;
  fetch(`http://localhost:3000/api/test/${id}`).then(res => res.json()).then(data => console.log(data)).catch(error => console.error(error));
}

I do see the data returned however, every now and then I see an ECONNRESET error. The amount of ECONNRESET error messages also vary: sometimes I get a few, sometimes a lot more. I do understand the message but I can't get my head around solving the issue behind it.

Here's a sample error:

{ FetchError: request to http://localhost:3000/api/test/8 failed, reason: connect ECONNRESET 127.0.0.1:3000
    at ClientRequest.<anonymous> (node_modules/node-fetch/lib/index.js:1345:11)
    at ClientRequest.emit (events.js:182:13)
    at Socket.socketErrorListener (_http_client.js:399:9)
    at Socket.emit (events.js:182:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process.internalTickCallback (internal/process/next_tick.js:72:19)
  message:
   'request to http://localhost:3000/api/departments/8 failed, reason: connect ECONNRESET 127.0.0.1:3000',
  type: 'system',
  errno: 'ECONNRESET',
  code: 'ECONNRESET' }

Note that I have tried to make the request using axios, the built-in HTTP module all to avail. I'm sure the issue is with my Express app handling the request but not sure how to fix it exactly.

Update 1:

As per the suggestion in the comment, here's the async version:

async function f() {
  const array = Array.from(Array(1000).keys());
  for (const el of array) {
    try {
      let id = Math.floor(Math.random() * 12) + 1;
      const result = await fetch(`http://localhost:3000/api/test/${id}`).then(res => res.json());
      console.log(result);
      return result;
    } catch(e) {
      console.log(e);
    }
  }
}

f();

Now I am receiving occasional ECONNREFUSED messages.

Update 2:

Based on Mazki516's answer here's the solution that works:

// previous require statements
const cluster = require('cluster');
const os = require('os');

if (cluster.isMaster) {
  const cpuCount = os.cpus().length
  for (let i = 0; i < cpuCount; i++) {
      cluster.fork()
  }
} else {
  const app = express();
  // rest of the route definitions
  // also app.listen() etc...
}
cluster.on('exit', worker => {
  console.log(`${worker.id} removed`);
  cluster.fork();
});
解决方案

One of the reasons you see this is because you make the calls in "parallel" .You do start the calls one after the other , but the loops will end probably before the first results returned from the server.The loop continues until the end , making the call stack filled with 1000 async requests to the server .

Your'e are hitting hardware/software limits and nothing is wrong with the code.if you did want to build a server which can handle 1k (and much more) requests concurrently I would take a look into the "cluster" module of node .

Please notice that when doing network job between server , it's acceptable to use a concurrency limit . (for example: up to 4 requests concurrently)

but you can always scale your server beyond one machine and handle much more traffic .

这篇关于具有多个请求的Express.js(Node.js)中的ECONNRESET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 18:10
查看更多