Unique Id - changnet/MServer GitHub Wiki
游戏中有多个场景需要用到唯一id:
- rpc回调(rpc id)
- 道具id(item id)
- 对象句柄(handle)
- 玩家唯一id(player id)
- 邮件id(mail id)
- 充值订单id(order id)
- 公会id(guild id)
持久化 | 服务器 | 应用服务器 | lua限制 | 数字 | 增长 | |
---|---|---|---|---|---|---|
rpc id | NO | NO | BETTER | NO | BETTER | NO |
handle | NO | NO | BETTER | YES | YES | NO |
mail id | YES | YES | NO | YES | YES | YES |
item id | YES | YES | NO | YES | BETTER | NO |
order id | YES | YES | NO | NO | YES | YES |
guild id | YES | YES | NO | YES | BETTER | NO |
player id | YES | YES | NO | YES | BETTER | NO |
- 持久化:是否需要存库。如果需要,此id通常作primary key
- 服务器: 是否需要保持两个服务器之间唯一。合服或者跨服战时需要。
- 应用服务器:是否需要保持两个应用服务器之间唯一。应用服务器之间通信需要。
- lua限制:lua是否能处理此类型数据。一般指lua 5.1能否处理int64.
- 数字:是否只能是数字。
- 增长:值的大小是否只能由小到大
参考UUID、mongo object id、twitter snowflake等常用分布式唯一id的处理办法,没有一个完 全适用上面的id。只能根据自己的服务器架构来重新设计适用的id.
服务器根据平台来区分,比如google play和appstore。每个平台又分为多个服,如google play 1服、2服等。国内众多平台多数是可以混服、合服的,因此要考虑唯一的服务器相关性。启动服务 器时,必须指定一个唯一的服务器索引srvid(uint16)。
每个服务器由多个应用服务器构成。应用服务器按种类区分,比如gateway、world、zone等,每一 类型都有一个唯一值type(uint8)。每个类型的应用服务器可以有一个或者多个,每个应用服务器在 当前服务器当前类型下有一个索引值index(uint8).
-
rpc id只与应用服务器相关,type + index + sequeue自增即可。异步rpc调用在内存中等待 的数量有限。当自增达到最大值时再次从0计数即可。其实,rpc调用从一个应用服务器发起,另一个 应用服务器收到后处理完,直接返回结果给对应的连接。而连接具有唯一性的,因此rpc id甚至可以 做到应用服务器不相关。
-
handle是指ARPG游戏中实体句柄,每一个怪物、NPC、掉落的物品,都需要唯一的句柄。由于实 体通信频率比较高,必须要求是数字,不然流量过大。由于lua 5.1最大可以处理52位,那么最简单 的方法就是不理会应用服务器相关。因为即使在多个应用服务器创建怪物,也应该知道当前是在哪个 应用服务器的。那么可以采用 32bit时间戳 + 20bit自增,这样可以满足持久化需求,比如存个副 本的handle。如果开发时确实需要应用服务器相关,则type + index + sequeue(32bit)这种组合 就满足要求了。不过重启后可能会重复。
-
邮件、充值存库主键使用mysql自己的自增或者MongoDB的objectid即可。另外需要一个自增id 来判断玩家是否已收取此邮件或发放此笔充值,采用 时间戳+计数 的方式。32bit时间戳+16位计数。 每秒可发65535封邮件或者65535笔充值,这对于游戏来说已经满足业务要求。并且48bit大小可由 lua表示(包括lua5.1)
案例1:
- actorId为32bit,13bit为serverid,19bit为自增id。自增存在数据库。
- handle为64bit,32bit为固定数组下标,16位自增。可能会重复。
- itemId为64bit,32bit时间戳,16bit服务器id,16bit自增
案例2: 这个框架数据库操作是阻塞的
- pid为52bit,由于是面向东南亚,采用平台号(10bit)+子平台号(12bit)+服务器号(10bit)+自增(20bit)。自增同样放数据库
- item直接使用uuid字符串
- 公会id、充值、邮件直接使用数据库自增,合服时取最大值即可
案例3:
- pid只是32bit数据库自增,由开服时设定表自增,然后用存储过程创建玩家,返回lastId给上层逻辑
- item使用类似uuid一样的字符串,但是是自己根据服务器号+时间戳+自增定义的。
0867a44e-b481-4fde-9b3c-1767b60702b6
http://www.iteye.com/topic/1134781 uuid转62进制