2012-03-25 58 views
1

使用EC2实例(以及Amazon Auto Scaling和Elastic Load Balancing)我有几个在Amazon Web Services中运行的TCP服务器实例。每个EC2实例都有权访问集中式数据库(在Amazon RDS上运行)。为了使这个后端可扩展,新的EC2实例(TCP服务器的实例)根据需求进行放大和缩小。在EC2实例上扩展TCP服务器的分布式问题

服务器已经使用Python Twisted框架制造。该系统支持自定义即时消息服务,可以加入多个群聊。

当用户开始使用服务时,他们与其中一个TCP服务器建立TCP套接字。每个服务器在内存中存储当前连接的用户(即,开放的TCP套接字)以及每个用户当前“进入”(并因此订阅)的“群组聊天”。所有创建的聊天数据都存储在数据库中。

的问题

当用户A职位GroupChatZ消息,所有用户在“GroupChatZ应收到该邮件。如果只有一个TCP服务器,这很简单:它将在'该群组聊天'中为其所有用户搜索内存并向他们发送新消息。但是,由于存在多个服务器,因此在创建新消息时,该服务器必须将消息传递给所有其他服务器(即EC2实例)。

这个问题最有效的解决方案是什么? 也许使用AWS组件。


一个解决方案,我能想到的是为每个服务器来存储它的IP地址在数据库中时,第一次启动,并得到其他所有连接的服务器的IP地址和与他们建立TCP连接。当收到每条新消息时,处理该消息的服务器可以将其发送给所连接的所有其他服务器。

但是,TCP连接不是100%可靠的,这种解决方案增加了复杂性。


我怀疑居然还有使用一些Amazon Web服务组件来实现一个简单的用户,出版商型机制的好办法(认为Observer设计模式)。即其中一台服务器添加了一些其他服务器实时收到的信息。

+0

快速更新,我刚刚开始关注Amazon SNS并创建每个Twisted服务器将订阅的主题。迄今为止的结果看起来很有希望 – 2012-03-27 01:27:23

回答

0

不仅是TCP连接不是100%可靠的,EC2实例也不是。他们可以随时消失(并相信我,他们有时会这样做)。实例的内部IP地址也可能会发生变化(例如,如果它重新启动)。如果您使用弹性IP地址,则来自AWS数据中心外部的连接(例如聊天客户端)将具有稳定(一组)IP连接。但是,使用弹性IP在服务器之间进行通信的速度相对较慢,因为连接路由到AWS防火墙之外,然后返回(上次无论如何检查)。

这里有一些策略来考虑:

  1. 使用较大的EC2实例,可以处理所有的连接,具有双机热备,如果您的可用性要求,从而决定。如果知道流量的上限(例如,如果这是一个企业聊天应用程序而不是面向互联网的应用程序),那么您可能会发现扩展比扩展更便宜,如果它可以极大地简化您的工程设计工作,则可以扩展。

  2. 如果您决定仍想扩展,请考虑使用事务性的分布式缓存(例如EH Cache)来存储聊天数据。这类问题已经解决。您将花费大量工程时间来处理已建立的分布式缓存之一已处理的所有情况。

+0

单个EC2实例没有冗余。您如何使配置更改或部署保持高可用性?缓存的想法是一个很好的例子。 – Diego 2012-03-25 18:00:21

+0

@Diego:如果他需要高可用性,他需要一个反映主服务器当前状态的热备份(选项#1)。如果在服务器停机的情况下可以容忍5到10分钟的停机时间,那么就可以拥有一个基于EBS的AMI,它可以在启动时知道如何从DB初始化聊天状态。它将接管原始服务器的弹性IP(可以在启动时编写脚本)。 – 2012-03-25 18:14:07

0

我认为Amazon SQS(简单队列系统)可以提供帮助。您为每个服务器创建一个消息队列。收到消息时,服务器将消息放入每个服务器的队列中。服务器频繁地轮询新消息的队列。如果服务器抓取指向未连接到该用户的用户的消息,则该消息将被忽略,否则将被传递。