如何将RabbitMQ的响应返回给浏览器

时间:2018-10-16 19:28:48

标签: php rabbitmq amqp php-amqplib

我正在尝试通过将复杂的数据库任务发送到RabbitMQ队列以由工作人员dyno处理来简化我的应用程序,以减少服务器负载。

对于INSERTUPDATE来说,这相对简单。但是,我要发送几个密集的SELECT到队列。但是,我遇到的问题是,准备就绪后如何将响应返回给用户的浏览器。

我知道我应该将响应发送到第二个队列,并在客户端的浏览器中创建使用者。但是,这样做会遇到一些实际问题,例如如何从队列中选择正确的响应,而不是简单地选择下一个响应(例如,如果两个人同时在页面上)。

有人有经验或建议吗?

谢谢

2 个答案:

答案 0 :(得分:1)

RabbitMQ网站上有a tutorial on building a request-response "RPC" flow,听起来像是您所追求的。

正如您所说,单个“响应”队列将不起作用,因为您无法选择从队列中取出哪些项目,因此可以将它们全部按顺序进行。相反,技巧是为每个客户端创建一个单独的响应队列(或者,对于最简单的实现,为每个请求创建一个响应队列)。

您可以通过声明“匿名”队列来实现此目的,该队列并不是真正的匿名,RabbitMQ为您选择了它的名称。然后,您可以将该名称作为请求的一部分发送(通常在AMQP消息的reply_to标头中),以便另一端的工作人员知道将响应发送到哪里。在php-amqplib中,如下所示:

list($reply_queue_name, ,) = $channel->queue_declare("", false, false, true, false);

注意:

  • queue_declare调用返回一个数组,其中包含队列的名称和状态;我们只需要名称,因此我们使用list()构造丢弃了数组的其余部分。
  • 队列名称作为空字符串传递,告诉服务器创建其选择的名称。
  • 第4个参数设置为true,以声明队列为“独占”;这意味着该连接结束后,队列将被清理。

答案 1 :(得分:0)

最后,我使用了不同于@IMSoP描述的方法。我很想听听关于哪种方法更有效或更有效的看法。

在排队的任务结束时,JSON响应被推送到Redis存储中(键是唯一的用户ID,值是JSON响应)。在浏览器中,AJAX用于每两秒钟运行一个PHP文件,该文件检查Redis存储库是否具有与用户ID匹配的密钥。找到后,它将值返回给浏览器,然后删除Redis上的key => value对。