我有 2 个不同的系统(A 和 B)使用 amazon sqs 进行通信. 系统A向系统B发送消息。
目前,系统 B 使用一个单独的线程获取消息,该线程在服务器启动时启动。 这是运行方法:
@Override
public void run() {
while (true) {
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl);
try {
receiveMessageRequest.setWaitTimeSeconds(1);
List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();
for (Message message : messages) {
// process messages
}
}
}
}
看着这段代码,我觉得它效率不高,因为它使用了一个繁忙的等待循环。 我希望使用某种推送机制来获取消息。
阅读一些关于亚马逊的文章 sqs和 sns这似乎可以使用 http(服务器 B 可以为此公开 servlet),但我仍然有点困惑。
- 哪个(sns 或 sqs)应该为我提供这种能力(将消息推送到服务器 B)?
- 最简单的方法是什么(对代码的任何引用)?
最佳答案
两者中,只有SNS可用于向系统B推送消息。SQS可用于让系统B轮询消息。
哪个是更好的解决方案取决于您的工作负载/应用程序要求。如果您使用 SNS,那么系统 A 生成的通知激增将导致系统 B 的工作负载激增,这可能无法处理负载。
如果您使用队列,负载峰值将由 Amazon SQS 缓冲,不会直接影响您的系统 B。这有助于将系统 B 与系统 A 分离,并在它们之间提供缓冲。这意味着您可以关闭系统 B,进行维护,然后恢复系统并像什么都没发生一样继续处理消息(假设您的应用程序可以处理消息的延迟处理)。
我在队列中看到的另一个主要优点是它使应用程序的扩展变得更简单,因为您可以启动一个运行消费者的新实例,现在您可以以更高的速率处理消息(假设您的系统中没有其他瓶颈) .
另一个考虑因素是消息传递语义。消息是乱序发送还是多次发送有关系吗?我没有太多使用 SNS,所以我不确定它的语义。 SQS 是一个分布式队列,因此您可能会乱序接收消息,甚至在某些情况下会收到多次消息。您的应用程序可以处理这个问题吗?
SQS 支持长轮询,允许您指定在 receiveMessage 调用返回之前等待消息的时间(最多 20 秒)。这可以限制您向 SQS 发出的请求数量,从而减少运行成本。这可能比 SNS 效率稍低,但在我使用 SQS 构建的应用程序中,它不值得担心。 参见 http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html .
例如,GitHub 上提供的 AWS Java SDK 包含各种 AWS 服务的使用示例。参见 https://github.com/aws/aws-sdk-java/blob/master/src/samples/AmazonSimpleQueueService/SimpleQueueServiceSample.java和 http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.example.java.html对于 SQS 和 SNS 示例。
您还可以结合使用 SNS 和 SQS。也就是说,您将消息推送到单个 SNS 主题,并让 SNS 将消息的副本推送到多个队列中。参见 http://docs.aws.amazon.com/sns/latest/dg/SendMessageToSQS.html
关于java - 使用 Java 的亚马逊 sns 和 sqs 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23927141/