问题描述
当使用AWS SQS和工作客户端进行事件驱动的工作处理时,通常建议使用长轮询。AWS在这里文档中对此进行了说明。基本上,当队列中没有消息时,工作进程不需要继续向队列发出请求(这样可以减少调用成本),但新的消息仍然会立即传递给进行长轮询的工作进程。我已经使用SQS构建了几个小系统,现在我对短轮询的好处产生了疑问。我想象它可能会稍微快一些,因为只有在短轮询时才会轮询SQS服务器的一个子集,但如果这是唯一的缺点,那么我会遇到什么样的额外延迟?这取决于我处理的消息数量吗?(SQS服务器是否根据消息数量进行扩展?)还有其他的缺点吗?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
根据基准测试结果显示,当队列满时,长轮询和短轮询之间的时间差异并不大。此外,长轮询始终会返回数据,而短轮询则不一定会返回数据。
至于何时使用短轮询,AWS的常见问题解答中有相关说明:
例如,如果您的应用程序使用单个线程轮询多个队列,从短轮询切换到长轮询可能不起作用,因为单个线程将等待任何空队列的长轮询超时,从而延迟处理可能包含消息的任何队列。
此外:
如果您的应用程序期望从ReceiveMessage调用中立即获得响应,则可能无法在不对应用程序进行一些修改的情况下利用长轮询。
如果您不想在应用程序中处理异步队列和多个线程处理队列,那么短轮询可能提供了更简单的开发路径(尽管您将不得不处理空响应)。
方案2
使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run
命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。
示例:
以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:
#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b
在这个示例中,我们首先使用docker run
命令启动容器A,并将其命名为container_a
。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo
命令来测试)。一旦容器A就绪,我们再使用docker run
命令启动容器B,并将其命名为container_b
。