awakeBird Back-end Dev Engineer

使用pkgen生成唯一id的问题

2018-09-09

之前项目中有通过pkgen生成唯一id作为token字符串使用,一直未发现问题。

token = PkGen().pkgen().pk

直到前些天在测试环境(服务器为阿里云)突然开始抛出异常。

查看pkgen源码发现下面几行:


@classmethod
def pkgen(cls):
    currtime = struct.pack('>i', int(time.time()))
    machine_signature = md5.new(
        socket.gethostname() + hex(uuid.getnode())[2:]).digest()[0:3]
    proc_signature = struct.pack('>H', os.getpid())
    with cls._lock:
        incr = struct.pack('>I', cls._incr)
        cls.incrby()
    _id = binascii.hexlify(
        currtime +
        machine_signature +
        proc_signature +
        incr[1:])

其中会通过将pid转换为字节流作为进程标签,转换格式>H为大端无符号short类型,两字节,其上限为2^16即65536。

而进程号为内核生成,除了init进程外无明确约定,其上限值根据操作系统位数不同而不同,32位机为32767,64位机为2^22,即4194304。

所以推测问题在这,果然登陆机器查看pid最大值结果如下:

而线上全部为32位机,所以暂时没有暴露问题。

可见利用pkgen生成唯一id的方式并不可靠,推荐使用uuid代替pkgen。

(End)


下一篇 Zookeeper全攻略

Comments

Content