import os
import asyncio
from time import time
import logging
from concurrent.futures import ProcessPoolExecutor
from sanic import Sanic
from sanic.response import text
# 一秒钟最多生成4096个ID
MAX_SEQUENCE = 2 ** 12
# 一个特殊的起始时间
EPOCH = 1259193600000
logger = logging.getLogger(__file__)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG)
class TimeBack(Exception):
"""时间回退"""
pass
class CounterOverFlow(Exception):
"""计数器溢出"""
pass
class Snowflake:
def __init__(self, worker_id=None):
# 计数器
self.sequence = 0
# 进程ID
worker_id = os.getpid()
self.worker_id = worker_id
self.last_time = int(time() * 1000)
def getid(self):
"""生成id"""
# current time
t = int(time() * 1000)
# Fatal Error
if t < self.last_time:
raise TimeBack("时间回退了")
# New Epoch
if t > self.last_time:
self.sequence = 0
self.last_time = t
# Counter
self.sequence += 1
# Fatal Error
if self.sequence >= MAX_SEQUENCE:
raise CounterOverFlow("计数器溢出了")
# 22 + 12 + 12 = 46
i = ((t - EPOCH) << 22) + (self.worker_id << 12) + self.sequence
logger.info("timestamp: %d, worker_id: %d, sequence: %d, id: %d",
t, self.worker_id, self.sequence, i)
return i
gen = Snowflake()
app = Sanic("snowflake")
@app.get("/id")
async def getid(request):
try:
i = gen.getid()
except (TimeBack, CounterOverFlow) as e:
return text(status=500)
else:
return text(i)
if __name__ == "__main__":
app.run(access_log=False)
算法十分的简单
输出:
timestamp: 1581933272553, worker_id: 6560, sequence: 5, id: 1353668299574607877
timestamp: 1581933272553, worker_id: 6560, sequence: 6, id: 1353668299574607878
timestamp: 1581933272553, worker_id: 6560, sequence: 7, id: 1353668299574607879
timestamp: 1581933272553, worker_id: 6560, sequence: 8, id: 1353668299574607880
timestamp: 1581933272553, worker_id: 6560, sequence: 9, id: 1353668299574607881
timestamp: 1581933272553, worker_id: 6560, sequence: 10, id: 1353668299574607882
timestamp: 1581933272553, worker_id: 6560, sequence: 11, id: 1353668299574607883
timestamp: 1581933272553, worker_id: 6560, sequence: 12, id: 1353668299574607884
timestamp: 1581933272553, worker_id: 6560, sequence: 13, id: 1353668299574607885
timestamp: 1581933272553, worker_id: 6560, sequence: 14, id: 1353668299574607886
timestamp: 1581933272553, worker_id: 6560, sequence: 15, id: 1353668299574607887
timestamp: 1581933272553, worker_id: 6560, sequence: 16, id: 1353668299574607888
timestamp: 1581933272553, worker_id: 6560, sequence: 17, id: 1353668299574607889
timestamp: 1581933272554, worker_id: 6560, sequence: 1, id: 1353668299578802177
timestamp: 1581933272554, worker_id: 6560, sequence: 2, id: 1353668299578802178
timestamp: 1581933272554, worker_id: 6560, sequence: 3, id: 1353668299578802179
timestamp: 1581933272554, worker_id: 6560, sequence: 4, id: 1353668299578802180
timestamp: 1581933272554, worker_id: 6560, sequence: 5, id: 1353668299578802181
timestamp: 1581933272554, worker_id: 6560, sequence: 6, id: 1353668299578802182
timestamp: 1581933272554, worker_id: 6560, sequence: 7, id: 1353668299578802183
timestamp: 1581933272554, worker_id: 6560, sequence: 8, id: 1353668299578802184
timestamp: 1581933272554, worker_id: 6560, sequence: 9, id: 1353668299578802185
timestamp: 1581933272554, worker_id: 6560, sequence: 10, id: 1353668299578802186
timestamp: 1581933272554, worker_id: 6560, sequence: 11, id: 1353668299578802187
timestamp: 1581933272555, worker_id: 6560, sequence: 1, id: 1353668299582996481
timestamp: 1581933272555, worker_id: 6560, sequence: 2, id: 1353668299582996482
timestamp: 1581933272555, worker_id: 6560, sequence: 3, id: 1353668299582996483
timestamp: 1581933272555, worker_id: 6560, sequence: 4, id: 1353668299582996484
timestamp: 1581933272555, worker_id: 6560, sequence: 5, id: 1353668299582996485
timestamp: 1581933272555, worker_id: 6560, sequence: 6, id: 1353668299582996486
timestamp: 1581933272555, worker_id: 6560, sequence: 7, id: 1353668299582996487
timestamp: 1581933272555, worker_id: 6560, sequence: 8, id: 1353668299582996488
timestamp: 1581933272555, worker_id: 6560, sequence: 9, id: 1353668299582996489
timestamp: 1581933272556, worker_id: 6560, sequence: 1, id: 1353668299587190785
timestamp: 1581933272556, worker_id: 6560, sequence: 2, id: 1353668299587190786
timestamp: 1581933272556, worker_id: 6560, sequence: 3, id: 1353668299587190787
timestamp: 1581933272556, worker_id: 6560, sequence: 4, id: 1353668299587190788
timestamp: 1581933272556, worker_id: 6560, sequence: 5, id: 1353668299587190789
timestamp: 1581933272556, worker_id: 6560, sequence: 6, id: 1353668299587190790
timestamp: 1581933272556, worker_id: 6560, sequence: 7, id: 1353668299587190791
timestamp: 1581933272556, worker_id: 6560, sequence: 8, id: 1353668299587190792
timestamp: 1581933272556, worker_id: 6560, sequence: 9, id: 1353668299587190793
timestamp: 1581933272556, worker_id: 6560, sequence: 10, id: 1353668299587190794
timestamp: 1581933272556, worker_id: 6560, sequence: 11, id: 1353668299587190795
timestamp: 1581933272556, worker_id: 6560, sequence: 12, id: 1353668299587190796
timestamp: 1581933272556, worker_id: 6560, sequence: 13, id: 1353668299587190797
timestamp: 1581933272557, worker_id: 6560, sequence: 1, id: 1353668299591385089