20

我正在尝试提出在 AWS 中扩展聊天服务的最佳解决方案。我想出了几个潜在的解决方案:

  1. Redis Pub/Sub - 当用户建立与服务器的连接时,该服务器订阅该用户的 ID。当有人向该用户发送消息时,服务器将使用该用户的 id 向通道执行发布。用户连接的服务器将接收消息并将其推送到适当的客户端。

  2. SQS - 我想过为每个用户创建一个队列。用户连接的服务器将轮询(或使用 SQS 长轮询)该队列。当发现新消息时,它将从服务器推送给用户。

  3. SNS - 在我发现 100 个主题限制之前,我真的很喜欢这个解决方案。我需要为每个用户创建一个主题,该主题仅支持 100 个用户。

他们还有其他方式可以使用 AWS 扩展聊天吗?SQS 方法可行吗?AWS 将消息添加到队列需要多长时间?

4

6 回答 6

10

建立一个聊天服务并不像你想象的那么容易。

我已经构建了完整的XMPP服务器、客户端和 SDK,并且可以证明出现的一些微妙和困难的问题。用户可以看到彼此并轻松聊天的原型。具有帐户创建、安全性、发现、存在、离线交付和朋友列表的全功能系统更具挑战性。然后在任意数量的服务器上进行扩展是特别困难的。

PubSub 是聊天服务提供的一项功能(参见 XEP-60),而不是构建聊天服务的传统方式。我可以看到它的魅力,但 PubSub 可能有缺点。

给你一些问题:

  1. 你是在网上做的吗?用户是要进行连接和长轮询,还是您有 Web Sockets 解决方案?

  2. 有多少用户?每个用户有多少连接?写入与读取的比率?

  3. 您以这种方式使用 SQS 的想法很有趣,但可能无法扩展。在聊天服务器上拥有 50k 或更多用户并不罕见。如果您为每个用户轮询每个 SQS 队列,那么您将无法获得任何结果。您最好为每个服务器设置一个队列,并且服务器仅轮询该队列。然后由您来确定用户在哪个服务器上并将消息放入正确的队列中。

我怀疑你会想要像这样的东西:

  1. 后端的大型 RDS 数据库。
  2. 一堆处理客户端连接的前端服务器。
  3. 一些中间层 Java / C# 代码跟踪所有内容并将消息路由到正确的位置。

要了解构建聊天服务器的复杂性,请阅读 XMPP RFC: RFC 3920 RFC 3921

于 2013-05-08T22:20:12.607 回答
9

SQS/SNS 可能不符合您的健谈要求。我们观察到 SQS 中的一些延迟可能不适合聊天应用程序。SQS 也不保证 FIFO。我曾在 AWS 上使用过 Redis。如果在配置时考虑到所有最佳实践,它会非常简单和稳定。

于 2013-05-29T17:05:09.617 回答
4

我曾考虑过使用 SNS 构建一个聊天服务器,但不是像您描述的那样为每个用户做一个主题,而是为整个聊天系统做一个主题并让每台服务器订阅该主题 - 每台服务器都在运行某种长轮询或网络套接字聊天系统。然后,当事件发生时,数据将在 SNS 通知的有效负载中发送。然后,服务器可以使用此有效负载来确定其队列中的哪些客户端应该接收响应,而任何不相关的客户端都不会受到影响。我实际上为此构建了一个小型原型,但尚未进行大量测试以查看它是否足够强大以供大量用户使用。

于 2014-05-12T14:24:02.283 回答
4

HI 实时聊天不适用于 SNS。它专为电子邮件/短信或服务 1 或几秒钟的延迟是可以接受的。在实时聊天中,1 秒或几秒是不可接受的。

检查这个链接

Latency (i.e. “Realtime”) for PubNub vs SNS

Amazon SNS 不提供延迟保证,并且绝大多数延迟的测量时间超过 1 秒,通常慢很多秒。同样,这有点无关紧要。Amazon SNS 专为服务器到服务器(或电子邮件/SMS)通知而设计,其中几秒的延迟通常是可以接受和预期的。

由于 PubNub 通过现有的、已建立的开放网络套接字传递数据,因此在 95% 的订阅设备中,从发布到订阅的延迟不到 0.25 秒。如果事件在 0.6 到 0.7 秒内被感知,大多数人会认为某事是“实时的”。

于 2017-03-18T13:15:33.697 回答
2

我将实现这样的事情的方式(如果不使用某些框架)如下:

有一个网络服务器(在 ec2 上),它接受来自用户的消息。在此网络服务器上使用 Autoscaling 组。网络服务器可以更新亚马逊 RDS 上可以轻松扩展的任何数据库。

如果您使用自己的数据库,您可以考虑使用 sqs 将数据库与网络服务器分离(通过将所有请求发送到同一个队列),然后您可以拥有一个消费队列的消费者。这个消费者也可以放在一个自动缩放组后面,这样如果队列大于 X msgs,它就会缩放(你可以用警报设置它)

sqs 通常更新非常快,即不到一秒。(从你发送它的那一刻起,到它出现在队列上的那一刻),而且很少有更多。

于 2013-05-24T14:28:00.483 回答
1

自从几个月前新的 AWS IoT 服务开始支持 WebSockets、Keepalive 和 Pub/Sub 以来,您可以轻松地在其上构建弹性聊天。AWS IoT 是一项托管服务,其中包含许多针对不同语言的 SDK,包括构建用于以零管理处理巨量负载(数十亿条消息)的 JavaScript。

您可以在此处阅读有关更新的更多信息:

https://aws.amazon.com/ru/about-aws/whats-new/2016/01/aws-iot-now-supports-websockets-custom-keepalive-intervals-and-enhanced-console/


编辑:

上次 SQS 更新 (2016/11):您现在可以将 Amazon Simple Queue Service (SQS) 用于需要使用先进先出 (FIFO) 队列以严格顺序处理消息并且只处理一次的应用程序。FIFO 队列旨在确保严格保留消息发送和接收的顺序,并且每条消息只处理一次。

资料来源: https ://aws.amazon.com/about-aws/whats-new/2016/11/amazon-sqs-introduces-fifo-queues-with-exactly-once-processing-and-lower-prices-for-标准队列/

现在,实施 SQS + SNS 看起来也是一个好主意。

于 2016-08-05T20:26:22.970 回答