miller
发布于

棋牌游戏软件服务器架构设计

想法
这个不是匹配的,是开好房间,再拉人那种。相对简单
斗地主等匹配类游戏,可以先check 有空位的房间===>没有就以此人为房主创建房间 。这样进化成上边开好房间匹配模式。对玩家而言不需要房间号,隐藏掉就好了。
后端roomId 还是要存着的

ps: node斗地主source
具体游戏逻辑参考.
参考2

棋牌游戏开发中由于棋牌游戏类的游戏数据少,计算量也小,所以可以不使用内存缓存,而直接使用 redis 共享内存,用户的所有数据都缓存在 redis 中。更新也同步更新到 redis 中,这样不管一个用户登陆哪一台业务服务器,都能获得自己的佳新数据。今天我们一起来了解下棋牌游戏游戏服务器架构设计。

一、棋牌游戏类服务器的特点

1、棋牌游戏类不分区不分服

一般来说,棋牌游戏游戏都是不分区不分服的。所以棋牌游戏类服务器要满足随着用户量的增加而扩展的需要。

2、房间模式

即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息。

3、每个房间的操作必须是顺序性

这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的。

二、需要解决的技术点

1、数据共享

因为棋牌游戏类游戏不分区不分服,我们在设计服务器的时候,是按世界服的思想去设计,即服务器是一个 n 多台物理机的集群。当用户登陆服务器,创建房间时,可能根据负载均衡算法,它可以在任何一台服务器上面。所以,不管用户登陆到哪一台服务器上面了,都可以获得自己的数据。我们可以使用 redis 来做数据共享。

2、如何进入房间

在同一局游戏中,我们要求所有人都在同一个房间中,我们可以规定在同一个房间中的用户,必须登陆到同一台物理服务器上面。在创建房间完成之后,其他人根据房间号查找房间的时候,可以根据房间号,获取这个房间所在的服务器 ip 和端口,判断一个当前用户登陆的服务器 ip 与房间所在的服务器 ip 是否相同,如果相同,就不做切换,如果不一样,客户端就使用 ip 和端口,连接到房间所在的服务器上面。

3、保证房间操作的顺序性

创建房间成功之后,接下来的操作都要保证它的顺序性,所以房间需要有一个它自己的消息个队列。我们可以把每个房间到达服务器的消息封装为一个任务,把这个任务放到消息队列中,然后有一个任务执行者去按顺序执行这些任务。

三、系统架构

1、功能设计

a、登陆

一般都是需要接第三方登陆,登陆这一块是 http 操作,我们统一提供一个 web 服务,用来做登陆验证。因为在登陆时,调用第三方的 http 服务,这个过程可能很慢,如果放在逻辑服务器的话,可能会卡业务逻辑任务。因为可能不同的玩家业务请求可能同在一个线程中,如果有任务卡了,那么这个任务以后新来的请求请会卡住,导致消息延迟。

b、获取游戏公告,也放在 web 服务中。公告一般是游戏登陆的时候向服务器获取一次。把它放在 web 服务器中,与业务逻辑分离的好处是,当业务逻辑服务器维护或更新的时候,不影响用户的登陆,和获取公告,这样用户体验会好一些。

c、创建用户的 id,因为棋牌游戏类游戏服务器是世界服,无分区,所以用户的 id 必须是全局的。可以利用 redis 的 incr 方法,原子的递增,如果不想被别人根据 userid 的递增推算出有多少注册用户,递增的梯度可以随机,比如每次递增的值从 1 到多 8 中随机一个。

d、创建房间,当房间主创建房间时,房间的 id 需要在任何台服务器上可以查询到,所以创建房间成功后,房间 id 要存储在共享内存 redis 中,每个房间 id 对应一个房间所在的 ip 地址或服务器 id. 这样,当有用户要进入房间,在查询房间 id 时,可能判断这个房间是否和自己登陆的游戏服务器相同。

e、查找加入房间,根据房间 id 查询房间,查找到房间后,获取房间所在的 ip 地址或服务器 id, 如果发现和自己所登陆的服务器一样,直接可以加入房间。如果不一样,把这个房间所在的 ip 和端口返回给客户端,让客户端重新与房间所在的服务器建立连接,使用登陆时的 token 验证用户。

f、游戏脚本调用,在验证游戏是否合法时,客户端与服务器都要验证,验证的算法是一样的,所以可以使用脚本来写,写一份脚本,在服务器与客户端中同时使用。可以使用 lua。同一个算法使用同一个脚本,这样在新的同类型棋牌游戏游戏时,只需要替换一下这个脚本就行了,不用再重复。

2、后台管理系统

这个一般是根据运营需求的,每个公司不一样。不过有一点,后台管理系统可能要和游戏服务器通信,这种通信方式佳好是采用 redis 的订阅 / 发布机制。这样可以把某个消息事件同时发送到所有的业务服务器上面。根据用户所在的服务器进行处理。

3、玩家同屏

玩家同屏是棋牌游戏游戏中的一个,对于做过那些大型的 arpg,或 mmo 游戏的程序员来说,这并不是什么难事。因为同屏就是服务器对客户端的消息进行转发。一个房间四个人,一个人出的牌或操作能被其他三个人同时看到

4、数据同步和持久化

由于棋牌游戏类的业务少,数据更新少,所以查询可以有 redis 缓存,减少数据库查询的压力,而更新实行实时更新到数据库,前期不需要数据库持久化服务。等用户积累到一定程序之后,发现更新数据库比较慢的时候,再单独做一个数据库持久化服务。

四、服务器架构

1、登陆时,客户端先向登陆的 web 服务器请求登陆信息,登陆成功之后,返回登陆的 token, 为了适应大规模的 web 请求和登陆服务的稳定,可以使用 nginx 做负载均衡。

2、登陆成功之后,请求负载均衡服务器,获取一台连接的业务服务器。这个负载均衡服务器可以和登陆 web 在一个进程中,也可以独立出来。

3、拿到登陆成功的 token 和需要连接的业务服务器的 ip 和端口之后,再去连接业务服务器。连接成功之后,要使用 token 到登陆服务器去验证,这个用户是否登陆了。

4、同一个房间的用户要连接到同一台物理服务器上面。在上面已经说过了。

5、redis 用来做共享缓存。

6、mysql 做持久化存储。

7、数据库持久化服务器,统一做数据入库操作。

原文地址 zhuanlan.zhihu.com

浏览 (747)
点赞
收藏
评论