如何用express处理多个并发请求?

问题描述 投票:0回答:1

我们希望在不使用节点集群的情况下有多个并发请求,即如果我们请求 3 次,那么我们应该几乎同时结束执行。

这是示例代码:

const execute_select = async () => {
    const jdbcres = new Driver(Conn.MySQL, {host, port, database})
    const d = await jdbcres.sql(‘SELECT * from db.maindb’); // takes 10 seconds to complete

}

app.post(‘/select, (request, response) => {
 execute_select();
 response.send(‘200’);
});

如果我们执行 http://localhost/select 3 次(同时),会发生以下情况:

  1. 我们立即得到回复。
  2. 每个请求都在以下行被阻止
    const d = await jdbcres.sql(‘SELECT * from db.maindb’)
  3. 第一个在 10 秒内结束,然后下一个在 10 秒内结束,然后是下一个,总共约 30 秒。

有没有办法让 /select 的调用不等待前一个请求结束,即总时间应该在 10 秒左右?

我的另一个尝试是用它代替以下行:

const d = await jdbcres.sql(‘SELECT * from db.maindb’); // takes 10 seconds to complete

/* const result = await new Promise((resolve, reject) => {
   setTimeout(() => {
        const d = jdbcres.sql('SELECT * from db.maindb')
        resolve(d);
    }, 20000);
    });
*/

请查找我已阅读过的相关页面列表:

  1. NodeJS Express 异步不处理更多请求
  2. 在 Express 服务器中使用 async/await 会阻塞所有正在使用的路由吗?
  3. NodeJS Express 异步不处理更多请求
  4. Node js Express 应用程序中使用 setTimeout 获取请求的并发性
node.js express asynchronous
1个回答
0
投票

你的谜语的答案是不要每次都等待新的结果,而是将请求的结果缓存为承诺,然后在每个后续请求中等待承诺的结果。

let dbCache = null;
const execute_select = () => {
    if(!dbCache){
      dbCache = new Promise(async (resolve, reject) => {
        const 
          jdbcres = new Driver(Conn.MySQL, {host, port, database}),
          d = await jdbcres.sql(‘SELECT * from db.maindb’); // takes 10 seconds to complete
        
        resolve(d);
        dbCache = null; // cache buster        
      })      
    } 
    return dbCache // now returns a Promise
}

app.post(‘/select, async (request, response) => {
 await execute_select();
 response.send("200");
});

  • 第一个请求将启动数据库执行并返回其承诺。
  • 第二个和任何后续请求将直接得到相同的承诺。
  • 直到承诺得到解决 -> 这也会清除缓存的结果

因此,您的 3 个示例请求总共将在 10 秒内得到处理,而不是像以前那样需要 30 秒。

另一种版本是在调用时缓存

execute_select
结果

const execute_select = async () => {
    const jdbcres = new Driver(Conn.MySQL, {host, port, database})
    const d = await jdbcres.sql(‘SELECT * from db.maindb’); // takes 10 seconds to complete
}

let dbCache = null
app.post(‘/select, async (request, response) => {
 if(!dbCache){
   dbCache = execute_select();
 }

 await dbCache.then(() => {
   dbCache = null
 })

 response.send("200");
});
© www.soinside.com 2019 - 2024. All rights reserved.