我正在工作,它代表用户处理一些输入数据(例如:价格计算参数),并生成输出(例如:计算价格)。计算最多可能需要20秒。
现在,我可以通过HTTP调用来访问计算。例如。
curl -X POST \
-H "Content-Type: application/json" \
--data '{"param1": "value"}' \
https://api.my-service.com/v1/calculate
我得到类似
的结果{ "price": 55.00 }
我们遇到了经典的可伸缩性问题。当我们达到每日峰值,并且有数百个并发请求时,响应时间将大大增加。因此,我想实现一个包含价格计算请求的队列。
我相信使用消息队列是我们前进的道路。我不想在这里介绍特定的技术,但是我们现在正在尝试RabbitMQ。
通常,体系结构如下所示:
client
▲
| HTTP
▼
------------------ -------------------
| Producer (service| | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation) | | | | | | | |
------------------ -------------------
我们需要通过网络浏览器或移动设备将价格计算的结果返回给用户。因此,一旦消费者完成计算,我们需要通知生产者。
我们可以建立第二个队列,一旦计算完成,消费者就可以在其中发布消息。生产者将收到该消息并将结果显示给用户:
client
▲
| HTTP
▼
------------------ -------------------
| Producer (service| | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation) | | | | | | | |
------------------ -------------------
<-- Feedback Queue --
虽然这可行且易于实现,但是像这样盲目地实现它意味着我们仍将在客户端和生产者服务之间保持HTTP请求打开。感觉像是很大的资源开销,而且好像没有真正解决我们的问题。
第二个选项:我们可以触发从客户端到生产者的请求,然后关闭HTTP连接。然后,客户端可以定期轮询生产者的更新,以查看计算是否已完成:
client
| HTTP: ▲
| calculate | HTTP: Poll until
| price! | calculation has
▼ | finished
------------------ -------------------
| Producer (service| | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation) | | | | | | | |
------------------ -------------------
<-- Feedback Queue --
我喜欢这种方法,因为它最大程度地减少了I / O开销并消除了任何HTTP超时问题。但这似乎只是消息传递模式的三心二意。
我确信必须有其他人实现了类似的用例并实现了任何一种解决方案。我正在寻找您的经验教训/错误和建议。