COC游戏服务器假象

896 views
Skip to first unread message

卓 一抗

unread,
Mar 6, 2013, 8:43:32 AM3/6/13
to erlang...@googlegroups.com
hi,大家好,最近在玩一款叫做<<clash of clans>>的slg手游,因为此游戏做的非常好,所以作为一名erlang开发者,不禁开始想象它的服务器应该怎样做。

下面是我的一点想法,欢迎交流讨论.


COC总图 整个游戏架构为 << router服务器+ 游戏逻辑服务器 >>

     router服务器:按玩家id索引其所在服务器                             
     玩家逻辑服务器:游戏逻辑计算+内存+硬盘
                                                       玩家 a   b   c  .... 若干
    +-----------+   索引     +----+   +----+                |   |   |  ....
    | router    |  ------>   | A  |   | D  |                |   |   |  ....   网络连接 tcp
    +-----------+            +----+   +----+             +-------------------+
                             +----+   +----+             |    游戏逻辑       |
    id - 名字                | B  |   | E  |             +-------------------+
         联盟                +----+   +----+             |    mnesia/ets     |
         服务器id            +----+   +----+             |-------------------|
         等级                | C  |   |  F |             |    Mysql          |
         奖杯数              +----+   +----+             +-------------------+


    << router服务器 >>    <<  玩家服务器集群 >>           << 逻辑服务器架构 >>

Router服务器: redis + mysql

 * router服务器是整个游戏架构的核心,它需要记录游戏中所有玩家的id和其附属信息,玩家在router服务器上查询到其所在逻辑服务器的id,并用逻辑服务器id取出逻辑服务器的ip+端口信息,与其建立连接,开始玩游戏。
 * router服务器的索引redis做,redis中只存储一个 {玩家id: 服务器id:}, 相信16G内存放的下,即便你有一亿用户.redis可持久化,可主从
 * 服务器具体信息使用msyql存储,即使有一个个服务器,也可以按{服务器id:服务器附属信息}加载到redis.可主从,可主从则可做slave服务器预防单点故障.
 * 不推荐使用hash的方法计算服务器id,因为服务器数目会增长,不方便取模,另一方面也不需要进行hash函数计算.
 * router服务器记录每个玩家的id和其所在服务器id,等级,联盟,奖杯数等信息
 * 提供相似度计算服务,为玩家选取实例相近的玩家.
 * 存储当前玩家是否锁定的状态.锁定状态不可打.

登陆过程

 * 先从router服务器登陆,验证用户信息等.router服务器需要记录玩家的账号密码,如果有的话.
 * 获取其所在服务器id,可根据id实时查询其所在逻辑服务器ip和端口,
 * 客户端直接与逻辑服务器通信,玩家可以开始玩游戏.

逻辑服务器

 * 在玩家逻辑服务器上,玩家完成城建,造兵等逻辑计算,这些操作不设计到玩家之间交互,做法简单。
 * 逻辑服务器采用mnesia作为内存cache,将活跃玩家数据全部load到mnesia中,方便快速检索;定时异步的将数据同步到mysql.
 * 设置活跃度参数,mnesia定时将活跃度低的玩家从内存中清除,节省内存.
 * 在逻辑服务器上查询玩家数据,先在mnesia中查,没有则从mysql中load数据到mnesia,再返回给查询客户端.
 * mnesia和mysql都可做主从,可预防单点故障.

pve

 * 当前玩家已通过tcp与其逻辑服务器A建立连接.
 * 在router服务器上按战斗力相似度查询其所在服务器B,当然锁定玩家不在查询范围之内.
 * 锁定玩家B,直接与玩家B所在服务器B通信,获取玩家完整信息状态,到服务器A.
 * 服务器A将抢钱结果同步到自己,服务器A将对方玩家设置到到服务器B.
 * 在线玩家不能打,不存在数据同步问题.

联盟

 * 也采用router + 联盟逻辑服务器架构,与玩家架构一致.
 * 在router服务器上按联盟id查询联盟所在服务器信息.
 * 与联盟逻辑服务器通信完成加入,退出联盟操作,以及获取联盟列表.

架构Scale

* 整个系统同时只有一个新玩家服务器,新用户全部导入到此服务器.
* 当新用户玩家服务器达到规定人数,开启新的新用户玩家服务器.
* 也可以合服和搬服,只需要维护好route服务器上的服务器id信息即可.

单点故障

* redis、mnesia 和 mysql 均可实现分布式主从,可分别建立slave服务器,当master故障时,定向到slave.

that's all.

Zhibin Zheng

unread,
Mar 6, 2013, 10:34:21 AM3/6/13
to erlang...@googlegroups.com
嗯,差不多了。还有就是要考虑一下排行榜。

大处没有什么问题,可是实现下去在细处需要想想,很多问题在细处。

例如,Clash of Clans的战争回放等。

看来现在都很多人在关注Clash of Clans,并且开始仿造一个了。想当年,大概2008~2009年的时候在之前的公司,也用Erlang做了一个和Clash of Clans类似的游戏的服务器。当时Code Update的时候会Block VM,现在R16B已经解决了。


--
您收到此邮件是因为您订阅了 Google 网上论坛的“Erlang China”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 erlang-china...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

Lihe Wang

unread,
Mar 6, 2013, 4:13:15 PM3/6/13
to erlang...@googlegroups.com
虽然没玩过那款游戏,但是整体上的思路看了一下。我觉得这个设计可能有问题:1、登录过程有没有可能成为颈?目前架构是单点验证,这其实不是erlang的思想。2、只考虑新人和加服务器,那么活跃度降低,退出登录的客户是不是了要占着资源呢?这可能没有达到最佳利用率。


Feng Yu

unread,
Mar 7, 2013, 9:27:20 AM3/7/13
to erlang...@googlegroups.com
感觉大家的架构做的都相当不错,学习了!

余锋(褚霸)
专注高性能容错分布式服务器,实践数据库存储引擎
http://blog.yufeng.info



2013/3/7 Lihe Wang <wanglihe....@gmail.com>

Lihe Wang

unread,
Mar 7, 2013, 7:37:22 PM3/7/13
to erlang...@googlegroups.com
霸爷!!您好。


卓 一抗

unread,
Mar 7, 2013, 8:17:15 PM3/7/13
to erlang...@googlegroups.com
hi,Lihe.

1,登陆过程有没有可能成为瓶颈=>

  因为router服务器要充当全游戏的玩家id索引,在登陆的时候和查找相似度玩家pvp的时候都需要router,是有可能成为瓶颈,目前我只考虑了redis能不能处理这么大量的请求的问题,以下是redis的benchmark:

测试完成了50个并发执行100000个请求。
设置和获取的值是一个256字节字符串。
Linux box是运行Linux 2.6,这是X3320 Xeon 2.5 ghz。
文本执行使用loopback接口(127.0.0.1)。
结果:写的速度是110000次/s,读的速度是81000次/s 。
如果有登陆验证,最好还是在玩家逻辑服务器上进行,以减少router的压力,也可简化设计

我想redis的性能即使是单机也可以满足很大的需要了,  如果多点router,应该怎么做呢?我还没有想到。。。

2,活跃度降低的玩家,降低内存的问题

因为游戏中需要设计一个活跃度参数,简称活跃值,能够根据玩家的登陆,玩游戏时间和pvp等参数来计算出来,玩家逻辑服务器需要定期将活跃值较低的玩家数据从内存中清除掉,并且在router服务器上也需要能够降低对活跃值较低的玩家的匹配。

根据手游的特性,预计搞个推广活动,带来2W玩家,第二天可能就只剩一半了,所以清除不活跃玩家可以大量节省内存。

卓 一抗

unread,
Mar 7, 2013, 8:22:47 PM3/7/13
to erlang...@googlegroups.com
zhibin说的很对,我这边是大概考虑了下整体,细节问题太多,不敢再细想下去,还是等要做类似的游戏的时候再想吧。

卓 一抗

unread,
Mar 7, 2013, 8:24:28 PM3/7/13
to erlang...@googlegroups.com
霸爷好,有时间对指点一下我们,我自己很多材料都是看着你的博客和ppt学习的。

Zheng Zhibin

unread,
Mar 8, 2013, 5:42:48 AM3/8/13
to erlang...@googlegroups.com
你说的Router问题,可以用Riak去做,或者自己实现一个router cluster。

BR.
Witeman

庆亮

unread,
Mar 8, 2013, 9:18:27 PM3/8/13
to erlang...@googlegroups.com
router不用考虑的如此复杂,mnesia单节点每秒几十W次的脏读写,在单机情况下完全顶得住
Reply all
Reply to author
Forward
0 new messages