Unique Id - changnet/MServer GitHub Wiki

唯一id

游戏中有多个场景需要用到唯一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).

  1. rpc id只与应用服务器相关,type + index + sequeue自增即可。异步rpc调用在内存中等待 的数量有限。当自增达到最大值时再次从0计数即可。其实,rpc调用从一个应用服务器发起,另一个 应用服务器收到后处理完,直接返回结果给对应的连接。而连接具有唯一性的,因此rpc id甚至可以 做到应用服务器不相关。

  2. handle是指ARPG游戏中实体句柄,每一个怪物、NPC、掉落的物品,都需要唯一的句柄。由于实 体通信频率比较高,必须要求是数字,不然流量过大。由于lua 5.1最大可以处理52位,那么最简单 的方法就是不理会应用服务器相关。因为即使在多个应用服务器创建怪物,也应该知道当前是在哪个 应用服务器的。那么可以采用 32bit时间戳 + 20bit自增,这样可以满足持久化需求,比如存个副 本的handle。如果开发时确实需要应用服务器相关,则type + index + sequeue(32bit)这种组合 就满足要求了。不过重启后可能会重复。

  3. 邮件、充值存库主键使用mysql自己的自增或者MongoDB的objectid即可。另外需要一个自增id 来判断玩家是否已收取此邮件或发放此笔充值,采用 时间戳+计数 的方式。32bit时间戳+16位计数。 每秒可发65535封邮件或者65535笔充值,这对于游戏来说已经满足业务要求。并且48bit大小可由 lua表示(包括lua5.1)

案例1:

  1. actorId为32bit,13bit为serverid,19bit为自增id。自增存在数据库。
  2. handle为64bit,32bit为固定数组下标,16位自增。可能会重复。
  3. itemId为64bit,32bit时间戳,16bit服务器id,16bit自增

案例2: 这个框架数据库操作是阻塞的

  1. pid为52bit,由于是面向东南亚,采用平台号(10bit)+子平台号(12bit)+服务器号(10bit)+自增(20bit)。自增同样放数据库
  2. item直接使用uuid字符串
  3. 公会id、充值、邮件直接使用数据库自增,合服时取最大值即可

案例3:

  1. pid只是32bit数据库自增,由开服时设定表自增,然后用存储过程创建玩家,返回lastId给上层逻辑
  2. item使用类似uuid一样的字符串,但是是自己根据服务器号+时间戳+自增定义的。

0867a44e-b481-4fde-9b3c-1767b60702b6

http://www.iteye.com/topic/1134781 uuid转62进制

⚠️ **GitHub.com Fallback** ⚠️