【问题标题】:How to make a Redis (Bull) queue in a Node.js environment that's deployed to Heroku?如何在部署到 Heroku 的 Node.js 环境中创建 Redis (Bull) 队列?
【发布时间】:2021-08-04 06:25:55
【问题描述】:

我查看了所有文档,但在查找正确实现的示例时遇到了一些麻烦。首先,我有 Heroku Redis 插件,如下所示:

https://i.stack.imgur.com/9kcXW.png

我将 Redis 和 Bull 安装到我的 Node.js 环境中,并按如下方式设置 Redis:

const redis = require('redis');
const Queue = require('bull');
const redisClient = redis.createClient(process.env.REDIS_URL, {
    tls: {
        rejectUnauthorized: false
    }
});
const bullQueue = new Queue('queue', process.env.REDIS_URL)

我正在尝试将以下函数作为后台任务运行(这是 Heroku 推荐的用于完成时间超过 0.5 秒的函数):

app.post('/', async function(request, response) {
  const client = await pool.connect() //pool is just a node-postgres pool
  try {
    await client.query('BEGIN')
    let data = await function1(argumentList);
    await function2(data);
    await client.query('COMMIT')
  } catch(err) {
    await client.query('ROLLBACK')
    console.log(err)
  }
  try {
    await client.query('BEGIN')
    const setOfItems = await function3()
    var array = []
    for (item of setOfItems) {
      if (conditional) {
        array.push(item)
      }
    }
    await client.query('COMMIT')
    let job = await bullQueue.add()
    response.send(JSON.stringify(array))
  } catch(err) {
    await client.query('ROLLBACK')
    console.log(err)
  }
});

这个函数做了一些网页抓取、数据库调用和其他事情,所以就像我说的,它需要几秒钟才能完成。我应该如何更改我的函数以将请求添加到后台队列,然后将 JSON.stringified 'array' 返回给用户。抱歉,如果这是一个菜鸟 Redis 问题,但我查看了所有文档,我真的不知道如何继续。

【问题讨论】:

    标签: javascript node.js heroku redis bull


    【解决方案1】:

    对于初学者来说,const redis = require('redis'); 不是必需的。 Bull 在后台连接到 Redis,因此您只需为 Heroku 提供 process.env.REDIS_URL 即可。 (heroku config | grep REDIS 在需要时返回端点 URL)

    目前,您的所有数据库代码都没有委托给任务队列。尝试使用

    注册与队列关联的处理函数
    bullQueue.process(job => {/* your database work goes here */})
    

    参数job 需要填充您的工作人员完成其工作所需的任何可序列化数据。您使用

    填充此参数
    bullQueue.add(/* job data goes here */)
    

    高级方法可能类似于:

    const Queue = require('bull');
    const bullQueue = new Queue('queue', process.env.REDIS_URL)
    
    bullQueue.process(async job => {
      console.log(job.data.argumentList);
    
      /* do SQL stuff */
      
      return [1, 2, 3, 4];
    });
    
    app.post('/', async (request, response) => {
      const job = await bullQueue.add({argumentList: ['some', 'data']});
      const array = await job.finished();
      response.send(JSON.stringify(array))
    });
    

    还有许多其他策略可用于获得结果。请参阅returning job completions 了解一些想法。

    另见:

    【讨论】:

    • 非常深入且解释清楚的答案,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    相关资源
    最近更新 更多