【问题标题】:Distributed queue wrapped with https request/response用 https 请求/响应包装的分布式队列
【发布时间】:2013-01-10 02:35:24
【问题描述】:

寻求有关如何执行以下操作的一些建议:

  1. 接收来自网站的请求,要求某个长时间运行的进程(~10-30 秒)
  2. 网站后端安排作业并放入分布式队列.. 可能是 SQS/Kue/resque
  3. 工作人员将作业从队列中取出并进行处理。将结果存储在某处。
  4. 网站后端订阅作业完成事件并获取已处理作业的结果。
  5. 网站后端使用任务结果关闭对网站的请求。

1,2 和 3 都可以。我只是发现将排队任务的结果传递回后端以便它可以关闭请求很棘手。

从网站轮询不是一个选项 - 无论任务需要多长时间处理,请求都必须保持打开状态。我正在使用nodejs。

【问题讨论】:

    标签: node.js queue task distributed


    【解决方案1】:

    2 - 4 都发生在服务器端。没有什么可以阻止您轮询结果的预期结果位置(在服务器端),然后在最终出现时返回结果。

    1. 客户端发送请求
    2. 服务器启动作业并开始轮询结果
    3. 返回结果,因此服务器端的轮询循环结束
    4. 服务器将结果发送回客户端
    5. 客户端-服务器连接终于被切断了

    如果作业可以在完成时执行一个 url,您可以获得更高效的代码。在这种情况下,您的服务将有两个端点……一个供客户端启动进程,另一个供您的作业队列调用。

    1. 客户端发送请求
    2. 服务器开始工作...将响应回调保存在一个全局对象中,这样它就不会关闭(我假设这里是 express 之类的)

      openJobs.push({ id: 12345, res: res }); jobQueue.execute({ id: 12345, data: {...}});

    3. 当作业完成并保存结果时,使用 id 调用服务 url

    4. 您可以检查作业是否实际完成并从 openJobs 列表中删除该作业
    5. 完成原始响应

      openJob.res.send(数据);

    6. 这将发送数据并关闭原始客户端-服务器连接。

    总体结果是您根本没有投票......这很酷。

    当然...在这两种情况下,如果您的服务器在批处理过程中关闭,您就会被搞砸...这就是为什么我会在这种情况下推荐类似 socket.io 的东西。您将在某处将作业的结果排队,socket.io 将轮询/等待列表上的回调,并在有新项目时推送到客户端。这更好,因为如果服务器崩溃没什么大不了 - 一旦服务器恢复,客户端将重新连接。

    【讨论】:

    • 感谢您的回答。我不确定将响应回调存储为全局状态是否是个好主意...
    • 是的,但从技术上讲,所有回调都存储在全局状态中(通常由 V8 引擎在内部完成)......任何回调都必须存储到最终被调用。在这种情况下,我们正在重构一个离开 js 环境的回调机制。
    • 所以我这样做了。几乎可以工作,但是在第二轮中,当我将res 存储在数组中然后将其拉回以关闭响应时,它会出现“发送后无法设置标头”的错误。现在,我绝对不会过早关闭回复。这是一个范围界定问题,导致res 始终是第一个响应,我不确定如何“释放”这个变量,所以它不会被关闭。
    • res 总是第一反应?你的意思是在你把它从阵列中拉出来之后?当我想在内容上发送一篇文章,然后再发送另一篇文章时,我通​​常会在使用 express 时遇到该错误,并且我错误地使用了“发送”命令(这会关闭请求)
    • 是的,如果我把它拉出来,如果阵列。是的,我很熟悉这个错误的含义。但我唯一一次关闭它是在我将它从数组中拉出来之后。所以我想弄清楚为什么它总是第一反应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多