首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java大规模多人游戏服务器可伸缩性

Java大规模多人游戏服务器可伸缩性
EN

Stack Overflow用户
提问于 2011-09-11 23:55:52
回答 3查看 8.9K关注 0票数 10

我为安卓系统创建了一个大型多人在线游戏,名为“无限的黑色:https://market.android.com/details?id=theinfiniteblack.client”。

在我幼稚的时候,我希望每个月有大约1000名玩家以中等速度增长,并且需要管理大约20个活动的TCP/IP客户端。

这款游戏在一周内爆发式增长,新用户超过4万人,平均一次有300个实时连接,而且还在呈指数级增长。

服务器体系结构由每个连接的两个线程组成(阻塞读/写),一个ServerSocket线程产生新的客户端,以及一个控制器线程轮询每个客户端的新操作,将其应用于游戏世界,然后在完成时刷新数据。

服务器是用我不太精通的Java构建的,特别是在像这样的高压力情况下。当涉及到内存和线程管理时,C#真的把我宠坏了。

开门见山..我刚刚订购了两个非常强大的系统作为专用游戏服务器运行,并希望最大限度地利用资源。有关Java资源配置的许多信息已被证明是误导性的、不正确的或过时的。

我目前使用-Xss512k作为我的启动参数,我知道这规定了每个线程的堆栈大小分配,但我并不完全理解它可能需要的所有内容。有什么工具或方法可以告诉我,如果我超标了,可以缩小它吗?我还应该考虑哪些其他命令行参数?

新的服务器有16 of的RAM和i7-2600K Sandy Bridge 3.4 The处理器:配置中有哪些选项可以尽可能地利用这一点?我的目标是每台服务器一次处理1200个在线客户端(2400个线程)。

我应该关注哪些意想不到的陷阱和问题?

我读过关于最大线程数的极大冲突的故事:如果我试图推送2400个活动线程,事情会崩溃吗?

Java看起来不像是为这类任务设计的。我是否应该考虑将服务器迁移到另一种语言?

我目前在Eclipse的调试模式下运行服务器,而它还在开发中(ugh..)

这是我的Eclipse .ini配置:

--launcher.XXMaxPermSize 256M

-Xms256m

-Xmx1024m

EN

回答 3

Stack Overflow用户

发布于 2011-09-12 01:21:59

你还没有说清楚你的怀疑来自哪里。

Plurk Comet: Handling 100,000+ Concurrent Connections with Netty (2009)

在1999年,我部署了一台Java web服务器,每小时处理40,000个黄页搜索查询(服务器有400个MHz ),在2004年,我开发了一个Java应用程序,每个服务器(在双1.2 GHz Sparc服务器上)处理8,000个并发连接,有六个网关服务器和一个主服务器来控制它们和集中事件。

您的个人资料可能会有所不同,但我可以说,在C#发布之前,Java就支持高容量的web服务器。

就我个人而言,每个服务器不会有超过10,000个并发连接,但这只是一个经验法则,可能不再适用。您可以在单个JVM中拥有32,000个线程。在Linux上,它不会超出这个范围。然而,我会在一台服务器上有多个网关JVM,以最小化完整的GC时间(最小化完整的GC时间的最好方法是丢弃更少的垃圾,但这可能需要更多的努力)

我的目标是每台服务器一次处理1200个在线客户端(2400个线程)。

我不能想象为什么这会是一个问题。

我应该关注哪些意想不到的陷阱和问题?

考虑到您需要转换所有可能的命令行参数,而您可能会将它们全部去掉。如果您有4个网关JVM,每个JVM有300个连接,则可以使用所有内存,甚至不需要指定-Xmx设置。

Java看起来不像是为这种类型的任务设计的。我是否应该考虑将服务器迁移到另一种语言?

你最好问问自己为什么相信这一点。你有一个应该很容易解决的问题,或者一个可能没有根据的怀疑。

这是我的

.ini配置:

配置eclipse方式对如何设置从eclipse运行的任何程序没有任何限制。

BufferedOutputStream适用于大多数应用程序,并且可能适用于JVM中多达1000个连接。然而,Java1.4 (2002)增加了NIO,对于将系统扩展到10,000个连接或更多连接而言,NIO是一个更轻量级的组件。

从那时起,我成功地使用了每个连接一个线程模型来阻塞NIO。我认为这比使用dispatcher更容易管理,并且可以具有更低的延迟特性。我有一个监视器线程,它定期检查连接是否在写入时阻塞,并在连接阻塞时将其关闭。我不相信每个连接需要两个线程,但我不相信这会对您的情况产生影响,因为您不会为每个服务器提供足够的连接。

正如glowcoder建议的那样,您是否考虑过对不太重要的广播信息使用UDP?

票数 8
EN

Stack Overflow用户

发布于 2011-09-12 00:01:34

在Java中,每个线程在堆栈上占用的内存量与其他线程相同。这意味着你的主线程,假设它的保留大小为32k (我认为这是默认值)将与你的通信线程的保留大小相同(如果你仔细想想,它可能只需要1k!)这就是为什么Java提出了nio --所以你不需要每个连接都有一个线程。

假设我们有一半的内存用于堆栈,另一半用于堆,每个线程有32k的内存,那么最终将有512个内存可用于堆栈。这为我们提供了16,384个线程的空间。现在,如果一个人挨饿了,那他就倒霉了;如果main挨饿了,倒霉死了……所有人!

有了nio你就有了..。两个线程。Main和通信。

Nio不一定是直观的学习,但它是值得的。

如果你不打算使用nio,我会考虑的一件事是每个连接只有一个线程,而不是两个。你不需要第二个线程来写:你可以有一个带有队列的线程,让它为所有的客户端做所有的写操作。这至少会使您的吞吐量增加一倍。

票数 4
EN

Stack Overflow用户

发布于 2015-06-19 04:50:56

你不能考虑节点的负载,也不要考虑线程的数量。1)如果您的游戏扩展到数百万用户,则需要通过注册表实现负载均衡的服务器集群

2)每个节点必须是低延迟的,这意味着每个传入的玩家消息和世界更新计算(1个滴答)必须以毫秒为单位完成。非常可行。不需要每个节点都有怪物配置。

3)每秒调用30次

=>您可以在单个节点上同时拥有数千名玩家,并通过区域分割将成千上万的玩家扩展到数百万人,这要归功于您的基础设施前面的注册表,该注册表确保玩家连接到最佳的ping延迟游戏服务器。

在此模式下,每个节点实时游戏加载10000名同时玩家,基于回合的游戏每个节点+300000名玩家。

瓶颈通常是IO。将SSD用于数据库存储。

Java不是问题。2400线程是一个问题。你可以用循环时间来解决这个问题,必须考虑在毫秒级的节拍循环下。

HTH

Nuggeta管理- 100% Free high load multiplayer java game server

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7379396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档