Python Fastapi 实现获取 Snowflake ID 接口,并用helm部署。

snowflake python 实现如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import random

#EPOCH 时间偏移量,从2019年6月16日零点开始
EPOCH = time.mktime((2019, 6, 16, 0, 0, 0, 0, 0, 0))
#SEQUENCE_BITS 自增量占用比特
SEQUENCE_BITS = 12
#WORKERID_BITS 工作进程ID比特
WORKERID_BITS = 5
#DATACENTERID_BITS 数据中心ID比特
DATACENTERID_BITS = 5
#NODEID_BITS 节点ID比特
NODEID_BITS = DATACENTERID_BITS + WORKERID_BITS
#SEQUENCE_MASK 自增量掩码(最大值)
SEQUENCE_MASK = -1 ^ (-1 << SEQUENCE_BITS)
#DATACENTERID_LEFT_SHIFT_BITS 数据中心ID左移比特数(位数)
DATACENTERID_LEFT_SHIFT_BITS = WORKERID_BITS + SEQUENCE_BITS
#WORKERID_LEFT_SHIFT_BITS 工作进程ID左移比特数(位数)
WORKERID_LEFT_SHIFT_BITS = SEQUENCE_BITS
#NODEID_LEFT_SHIFT_BITS 节点ID左移比特数(位数)
NODEID_LEFT_SHIFT_BITS = DATACENTERID_BITS + WORKERID_BITS + SEQUENCE_BITS
#TIMESTAMP_LEFT_SHIFT_BITS 时间戳左移比特数(位数)
TIMESTAMP_LEFT_SHIFT_BITS = NODEID_LEFT_SHIFT_BITS
#WORKERID_MAX 工作进程ID最大值
WORKERID_MAX = -1 ^ (-1 << WORKERID_BITS)
#DATACENTERID_MAX 数据中心ID最大值
DATACENTERID_MAX = -1 ^ (-1 << DATACENTERID_BITS)
#NODEID_MAX 节点ID最大值
NODEID_MAX = -1 ^ (-1 << NODEID_BITS)

def parse(id):
    r = {}
    r['timestamp'] = id >> TIMESTAMP_LEFT_SHIFT_BITS
    r['time'] = EPOCH + (id >> TIMESTAMP_LEFT_SHIFT_BITS) / 1000.0
    r['node'] = (id >> WORKERID_LEFT_SHIFT_BITS) & (-1 ^ (-1 << NODEID_BITS))
    r['sequence'] = id & SEQUENCE_MASK
    return r

def generate(workerID, datacenterID, sleep=lambda x: time.sleep(x/1000.0)):
    assert workerID >= 0 and workerID <= WORKERID_MAX
    assert datacenterID >= 0 and datacenterID <= DATACENTERID_MAX

    timestamp = 0
    sequence = 0

    while True:
        now = int((time.time() * 1000) - (EPOCH * 1000))

        if timestamp > now:
            sleep(timestamp - now)
            continue

        if now == timestamp:
            sequence = (sequence + 1) & SEQUENCE_MASK
            if sequence == 0:
                sleep(1)
                continue
        else:
            sequence = random.randint(0, 9)
        timestamp = now
        yield ((timestamp << TIMESTAMP_LEFT_SHIFT_BITS) |
            (datacenterID << DATACENTERID_LEFT_SHIFT_BITS) |
            (workerID << WORKERID_LEFT_SHIFT_BITS) |
            sequence)

if __name__ == "__main__":
    s = generate(1, 1)
    print(s.next())
    id = s.next()
    print(parse(id))

部署环境参考 helm 安装 bitnami/nginx-ingress-controller

编译镜像

1
docker build -t fastapi_shortcode:v0.2 -f app.Dockerfile .

打包helm安装包

1
2
helm package fastapi-short-code --debug --version 0.1.3
Successfully packaged chart and saved it to: /Users/piao/data/golang/helm-charts/fastapi-short-code-0.1.3.tgz

发布到helm仓库

1
helm repo index --url https://piaohua.github.io/helm-charts/ --merge index.yaml .

helm安装启动fastapi服务

1
helm install shortcode fastapi-short-code-0.1.3.tgz --namespace shortcode-ns

获取id

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
curl -X 'POST' \
  'http://www.example.com:30547/api/id' \
  -H 'accept: application/json' \
  -d ''

# Response body
{
  "id": 659064147358515200
}

# Response headers
access-control-allow-origin: * 
access-control-expose-headers: X-Request-ID 
connection: keep-alive 
content-length: 25 
content-type: application/json 
date: Fri,07 Jun 2024 16:05:37 GMT 
x-request-id: 932f12e64e0bbb74fac961bf1a6f59ff 

解析id

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
curl -X 'POST' \
  'http://www.example.com:30547/api/659064147358515200/parse' \
  -H 'accept: application/json' \
  -d ''

# Response body
{
  "timestamp": 157133137550,
  "time": 1717776337.55,
  "node": 0,
  "sequence": 0
}

# Response headers
access-control-allow-origin: * 
access-control-expose-headers: X-Request-ID 
connection: keep-alive 
content-length: 69 
content-type: application/json 
date: Fri,07 Jun 2024 16:05:52 GMT 
x-request-id: 630b2489086e3a8968ae67189e0b97f6 

参考