关于 koa 的并发问题,寻求多个请求同时处理的解决方案。
发布于 14 天前 作者 daGaiGuanYu 992 次浏览 来自 问答

我按照 koa 文档里的步骤,写了几个接口,发现由于使用 await/async 请求不能被并发处理。必须一个请求处理完才能处理下一个请求,cpu 有很多空闲时间。 有没有办法解决这个问题?

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  console.log('收到请求');
  ctx.body = await getResult();
  console.log('已响应');
});

app.listen(3000);

async function getResult(){
  return new Promise( resolve => {
    setTimeout( resolve, 5000, {
      data: 'hello, world'
    });
  })
}

以上代码,在浏览器里同时打开(快速打开两个 localhost:3000),可以看到本例问题所在。

10 回复

用 ab 做下压测,或者用不同浏览器同时打开 就明白了~

@zuohuadong 感谢。没用过 ab……不同浏览器打开确实就没这个问题了,为什么呢?

@daGaiGuanYu 大概是浏览器有个某个优化的策略,对同一个 URL 的资源同一时间只进行一个活动请求。可以 terminal 中开几个 tab,用 curl http://127.0.0.1:3000/ 在几个 tab 中同时试一下

这个问题是因为如果用chrome不同的tab打开同一个url的时候,每个tab会等待前面一个tab执行完才会执行

https://stackoverflow.com/a/14119399/1805188

https://stackoverflow.com/questions/27513994/chrome-stalls-when-making-multiple-requests-to-same-resource

见笑了,我还以为是不能并发处理……

楼主示例使用 ab 测试的确能并发,但为什么下面的例子(大量计算)却不能并发:

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  console.log('收到请求');
  ctx.body = await getResult();
  console.log('已响应');
});

app.listen(3000);

async function getResult(){
  return new Promise( resolve => {
    let sum = Math.PI;
    for (let i = 0; i < 100000000; i++) {
      sum /= 1.2;
    }
    resolve(sum);
  })
}

@xuxu7 高CPU计算把主进程占满了,怎么能并发呢

@waitingsong 谢谢,看了下 CPU,其中1核占用了 99.9%

@xuxu7 换个说法: 如果CPU都被占满了,此时多进程/线程模式又有何用处呢。

嗯,我对 Node.js 还没有深刻的理解,想验证下异步 io,结果 CPU 占满了没能验证。

回到顶部