我有一个大型游戏引擎,服务于手机客户端和网站。数据库是 MSSQL2008,引擎是用 C# 编写的。
该网站是使用 ASP.NET MVC 构建的,并且手机的 Web 服务也是基于 ASP.NET MVC 构建的(可能会迁移到 WCF 或纯套接字服务器)。
网站和 Web 服务位于 IIS 7 服务器上,数据库位于专用服务器上。两者都连接到本地快速 LAN。
游戏要求每个用户都有实时响应(1 秒内)。当我对服务进行一些负载测试时,似乎在约 250 个用户的情况下,响应时间达到 1 秒(50 个用户的情况下约为 200 毫秒)。它应该可以支持超过 10000 个用户连接。(我猜是服务器复制)。
我考虑再添加一层——一个用于游戏 Web 服务的专用实时服务器。我听说 Python 可用于构建非常高性能的服务——添加这一层是一个聪明的想法吗?(该层应该有内存临时数据库来为实时玩家提供服务,然后每隔 X 秒将其全部转储到后端数据库)。
我的架构好吗?如何改进?
答案1
我可以谈谈 SQL Server 部分。
您的硬件规格是什么?您使用的 SQL Server 版本是什么?虽然您可以向机箱添加更多内存并将数据保存在内存中,但一段时间后该解决方案将无法扩展。如果您想为许多用户扩展,您需要在这里使用许多好的做法。
常见的瓶颈是内存、IO、CPU。
- 拥有更多记忆会有所帮助。
- 拥有良好的磁盘系统 [RAID 10] 确实很有帮助。将数据和事务日志分离到不同的主轴上是一种很好的做法。根据 IO 量,将 tempdb 移到其自己的主轴上并查找瓶颈。它是否受 IO 或分配瓶颈的限制。使用跟踪标志 TF 1118 和许多 tempdb 数据文件会有所帮助。
- 预先分配数据和日志文件,以便它不会在正常业务操作期间自动增长。
- 经过一番尽职调查后,从好的架构 + 好的代码开始。不管你使用什么平台,糟糕的代码就是糟糕的代码,输入垃圾就是输出垃圾。
- 非常了解索引结构并有良好的索引维护计划(更新统计数据)
- 使用大量数据对你的 SQL 代码进行负载测试。
- 了解如何识别 SQL Server 中的瓶颈和性能问题。等待统计数据和虚拟文件统计数据在这里非常重要。根据 cu、逻辑 IO 和高执行次数确定哪些过程是昂贵的。查看缺失索引 DMV。学习从 SQL Server 计划缓存中读取数据。
- 查看即时文件初始化
- 这里还有许多其他东西,很难一一列出。这是一个很好的起点,但它并不是一份详尽的清单。
http://www.sqlskills.com/BLOGS/KIMBERLY/category/Indexes.aspx
http://www.sqlskills.com/BLOGS/PAUL/category/Indexes-From-Every-Angle.aspx
答案2
在我看来,你应该首先问自己瓶颈在哪里。
- 大多数情况下,SQL 服务器是磁盘 IO 的重度消耗者;这本身就是一个优化主题(数据库架构、SQL 查询与 StoreProc 等)。您可能需要使用 SQL 探查器。
- 您是否使用 Web 服务的任何状态机制?如果是,您是否使用 SQL 服务器来保存该状态?这可能是一个性能问题。
- 您是否尝试过分析您的.Net 代码和 SQL 查询代码?
- 您是否通过 SOAP 发送二进制块,二进制内容需要以 base64 进行编码,这可能会导致一些开销(网络和带宽),与 SSL 相同;
- 您是否问过自己是否使用除 WebService/SOAP 之外的非语言协议;也许是 HTTP/JSON 协议,甚至是自定义二进制协议。
- 构建一个 python 代理是一件有趣的事情,但我很确定您可以使用.Net 和 Windows 服务实现类似的概念,但您可能还会问自己代价是什么,因为如果您需要对整个事物进行集群,您将需要在其上添加更多的同步和稳健性(防崩溃)功能。
答案3
该游戏要求每个用户都能实时响应(1秒以下)。
这些是移动电话用户,使用不同的服务质量(3G/3Gs/4G/wi-fi)、接收、延迟、抖动、碎片化等,而您期望响应时间小于 1 秒?您是否使用以下设备测试过一更别说几百部手机了?
答案4
- 游戏服务器通常采用基于UDP协议的自定义协议
- 需要从底层为该协议创建服务器,据我所知,没有公共框架或其他东西可以提供帮助
- 对于存储状态,请使用内存或一些缓存,而不是 SQL DB