在Facebook应用程序和云计算时代,我正在重新考虑大规模多人游戏。

假设我要在现有的开放协议之上构建一些东西,我想同时为100万个玩家服务,以解决问题。

假设每个玩家都有一个传入的消息队列(用于聊天和Whatnot),平均一个传入的消息队列(公会,区域,实例,拍卖,...),所以我们有2,000,000个队列。玩家一次听1-10个队列。每个队列平均每秒可能有1条消息,但是某些队列的速率和更高的听众数量(例如,对于级别实例的“实体位置”队列)。让我们假设不超过100毫秒的系统排队延迟,这对于轻度以动作为导向的游戏(而不是诸如Quake或Unreal Tournament)的游戏是可以的。

从其他系统来看,我知道在一个1U或刀片盒上为10,000个用户提供服务是一个合理的期望(假设没有其他昂贵的事情发生,例如物理模拟或什么)。

因此,使用横梁群集系统,客户端连接到连接网关,而连接网关又连接到消息队列服务器,我们每个网关使用100台网关的每门网关获得10,000个用户,而每排队用100台排队机器的每个排队队列服务器都会获得20,000个消息队列。同样,只是为了一般范围。每台MQ机器上的连接数量很小:大约100个与每个网关交谈。网关上的连接数量将更高:客户端 +与所有队列服务器的连接10,100。 (最重要的是,为游戏世界仿真服务器等添加一些连接,但我现在试图将其分开)

如果我不想从头开始构建这个,我必须使用一些存在的消息传递和/或排队的基础架构。我可以找到的两个开放协议是AMQP和XMPP。 XMPP的预期用途更像是该游戏系统所需的内容,但是开销非常明显(XML,加上冗长的存在数据,以及必须在顶部构建的各种其他渠道)。 AMQP的实际数据模型更接近我上面描述的内容,但是所有用户似乎都是企业型公司,工作负载似乎与工作流程相关,而不是与实时游戏更新有关。

您是否可以分享这些技术或实施这些技术或实施的任何白天经验?

有帮助吗?

解决方案

@msalters

重新“消息队列”:

RabbitMQ的默认操作正是您所描述的:瞬态pubsub。但是使用TCP而不是UDP。

如果您希望保证最终的交付以及其他持久性和恢复功能,那么您也可以选择 - 这是一个选择。这就是RabbitMQ和AMQP的全部要点 - 您只需一个消息传递系统就可以有很多行为。

您描述的模型是默认行为,它是瞬态,“火与忘记”,并将消息路由到接收者所在的任何地方。仅出于这个原因,人们使用RabbitMQ在EC2上进行多播发现。您可以通过Unicast TCP Pubsub获得UDP类型的行为。整洁,是吗?

reudp:

我不确定UDP在这里是否有用。如果您关闭nagling,则在250-300微秒处测量了RabbitMQ单消息往返延迟(客户端传播延迟)。请参阅此处的与Windows延迟的比较(有点高) http://old.nabble.com/high%28er%29-latency-with-1.5.1--p21663105.html

我想不出许多需要低于300微秒的往返潜伏期的多人游戏。您可以使用TCP低于300US。 TCP窗口 比原始的UDP贵,但是如果您使用UDP来更快,并添加自定义损失重新发现或seqno/ack/repent Manager,则可能会再次减慢您的速度。这完全取决于您的用例。如果您真的真的需要使用UDP和Lazy Acks等等,那么您可以剥离RabbitMQ的TCP,并可能将其删除。

我希望这有助于澄清为什么我推荐兔子的用例。

其他提示

实际上,我现在正在构建这样的系统。

我对包括RabbitMQ,QPID和Zeromq在内的多个MQ进行了相当多的评估。这些应用程序的延迟和吞吐量足以适应这种类型的应用程序。但是,不好的是队列创建时间在半百万或更多的排队中。 QPID尤其是在排队几千次后会严重降解。为了解决这个问题,您通常必须创建自己的路由机制(总排队数量较少,而这些队列的消费者正在收到他们没有兴趣的消息)。

我当前的系统可能会使用Zeromq,但以相当有限的方式使用 里面 集群。客户的连接使用自定义模拟。我使用libev构建的守护程序,并且完全是单线程(并且表现出非常好的缩放 - 它应该能够在一个盒子上处理50,000个连接而没有任何问题 - 我们的sim。没有物理)。

XML(以及因此XMPP)非常不适合此,因为您将在I/O绑定之前很早就使用CPU处理XML,这不是您想要的。目前,我们正在使用Google协议缓冲区,这些缓冲区似乎非常适合我们的特定需求。我们还将TCP用于客户端连接。过去,我曾经对此同时使用UDP和TCP的经验,正如其他人所指出的那样,UDP确实具有一定的优势,但是使用效果稍难。

希望当我们更接近启动时,我将能够分享更多详细信息。

乔恩(Jon),这听起来像是AMQP和RabbitMQ的理想用例。

我不确定您为什么说AMQP用户都是大型企业型公司。我们超过一半的客户在“网络”空间中,从巨大到小公司。许多游戏,投注系统,聊天系统,Twittery类型系统和云计算是由RabbitMQ构建的。甚至还有手机应用程序。工作流只是许多用例之一。

我们试图跟踪这里发生的事情:

http://www.rabbitmq.com/how.html (确保您也单击Del.icio.us上的用例列表!)

请看看。我们在这里为您提供帮助。请随时通过info@rabbitmq.com向我们发送电子邮件,或在Twitter(@monadic)上打我。

FWIW对于中间结果并不重要的情况(例如定位信息)QPID具有“最后值队列”,只能向订户提供最新值。

我的经验是一个非开放式替代方案BizTalk。我们了解到的最痛苦的教训是,这些复杂的系统并不快。正如您从硬件要求中所想象的那样,直接转化为巨大的成本。

因此,甚至不要接近XML的核心接口。您的服务器群集将每秒解析200万条消息。这很容易是XML的2-20 GB/秒!但是,大多数消息将用于几个队列,而大多数队列实际上是流量低的。

因此,设计您的体系结构,以便从COTS队列服务器开始,然后在确定瓶颈时将每个队列(类型)移至自定义队列服务器。

另外,出于类似的原因,不要假设消息队列体系结构是您应用程序所拥有的所有共识需求的最佳选择。以您的“实体位置”为例。这是您的经典案例 想要保证的消息传递。您需要共享此信息的原因是因为它一直在改变。因此,如果丢失消息,您不想花时间恢复它。您只会发送受影响实体的旧位置。相反,您要发送 当前的 该实体的位置。从技术角度来看,这意味着您需要UDP,而不是TCP和自定义损失机制。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top