Giao diện
Hướng dẫn cài đặt — Worker ID Allocator Redis
Yêu cầu
| Thành phần | Yêu cầu |
|---|---|
| Digiforce Server | Đang chạy trong chế độ cluster (nhiều instance) |
| Redis | Đang hoạt động và có thể kết nối từ tất cả instance |
Khi nào cần plugin này?
Plugin cần thiết khi:
- Chạy nhiều instance Digiforce cùng lúc (cluster/scaling)
- Cần Snowflake ID không trùng lặp giữa các instance
- Dùng Docker/Kubernetes để deploy
Không cần khi chỉ chạy 1 instance — allocator mặc định (in-memory) đủ dùng.
Bước 1: Đảm bảo Redis đã cấu hình
Plugin sử dụng Redis qua app.redisConnectionManager — cần đảm bảo Redis đã được cấu hình cho ứng dụng:
bash
# .env
REDIS_URL=redis://localhost:6379Hoặc với authentication:
bash
REDIS_URL=redis://:password@redis-host:6379/0Bước 2: Kích hoạt plugin
Vào Settings → Plugin Manager, tìm plugin-workerid-allocator-redis và bật.
Hoặc kích hoạt qua dòng lệnh:
bash
yarn pm enable plugin-workerid-allocator-redisKhi kích hoạt, plugin đăng ký adapter trong event beforeLoad:
typescript
app.workerIdAllocator.setAdapter(new WorkerIdAllocator(app));Bước 3: Kiểm tra
Khởi động server và kiểm tra log:
[info] worker id manager initialized with identifier: 192.168.1.100
[info] Allocated worker ID: 0Kiểm tra Redis keys
bash
redis-cli
> KEYS snowflake:worker:*
1) "snowflake:worker:main:0"
> GET snowflake:worker:main:0
"192.168.1.100"
> TTL snowflake:worker:main:0
(integer) 118Chi tiết kỹ thuật
Identifier
Plugin tự xác định identifier cho instance theo thứ tự ưu tiên:
| Ưu tiên | Nguồn | Khi nào dùng |
|---|---|---|
| 1 | process.env.POD_IP | Kubernetes — IP của pod |
| 2 | Local IP (non-container) | Máy vật lý hoặc VM |
| 3 | process.env.HOSTNAME hoặc os.hostname() | Container Docker |
Cơ chế cấp phát
Plugin duyệt từ ID 0 đến 31, dùng SET ... NX EX (atomic) để thử chiếm:
SET snowflake:worker:main:0 192.168.1.100 EX 120 NXNX= chỉ set nếu key chưa tồn tạiEX 120= key tự hết hạn sau 120 giây
Nếu ID 0 đã bị chiếm, thử 1, 2... cho đến khi thành công.
Cơ chế gia hạn (Renewal)
Mỗi 60 giây, plugin chạy Lua script atomic:
lua
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('EXPIRE', KEYS[1], ARGV[2])
else
return 0
endScript kiểm tra identifier trước khi gia hạn — tránh gia hạn key của instance khác.
Nếu gia hạn thất bại, plugin retry tối đa 3 lần.
Cơ chế giải phóng (Release)
Khi instance shutdown gracefully, plugin xóa key bằng Lua script tương tự:
lua
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
endNếu instance crash (không shutdown gracefully), key tự hết hạn sau 120 giây.
Fallback khi không có Redis
Nếu không kết nối được Redis, plugin trả về random ID (0-31):
typescript
return Math.floor(Math.random() * 32);Cảnh báo
Random ID có thể trùng lặp! Fallback chỉ để tránh crash — không nên dùng trong production mà không có Redis.
Triển khai trên Kubernetes
Đặt biến môi trường POD_IP trong deployment:
yaml
spec:
containers:
- name: digiforce
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIPPlugin sẽ dùng POD_IP làm identifier, đảm bảo mỗi pod có identifier duy nhất.
Lưu ý quan trọng
- Tối đa 32 instance (maxWorkerId = 31) — đủ cho hầu hết cluster
- Nếu tất cả 32 ID đều bị chiếm, plugin throw Error — instance không khởi động được
- Lease TTL 120 giây > Renewal interval 60 giây — đảm bảo không bị mất lease giữa 2 lần gia hạn
- Redis cần uptime cao — mất Redis không ảnh hưởng instance đang chạy (vẫn giữ ID), nhưng instance mới không cấp phát được