a distributed sequence number generator based on MySQL.
Need a human call number on some cases(Restaurant etc...).
CREATE TABLE `seqno_generator` (
`id` bigint(18) NOT NULL AUTO_INCREMENT,
`logic_id` char(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`prefix` char(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`last_id` bigint(18) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uni` (`logic_id`,`prefix`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
//Open a gorm instance
db, err := gorm.Open("mysql", "root:root@tcp(mysql:3306)/xxx?parseTime=true")
if err != nil {
b.Fatal(err)
}
seqno := NewSeqNoGenerator(db, "test-logic-id").
PrefixFormat("2006-01-02").
Step(1).
Locker(NewRedisLocker(
&redis.Pool{
MaxIdle: 5,
IdleTimeout: 30 * time.Second,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "redis:6379")
},
},
))
num,err := seqno.Next()
Logic ID
represents a concrete business logic(like order
,user
).
Incremental step. default is 1
Starting number. default is 1
date time format. default is empty. it's mean always use same increment queue.
if set PrefixFormat
to 2006-01-02
, it's mean go to zero once a day.
locker is a distributed locker interface. already have redis & ETCD implementation on standard library.
- Lock currently logic id.
- Insert or Update New Value to MySQL(depend feature
DUPLICATE KEY UPDATE
). - get last id.
- Unlock logic id.
2 locker call and 2 MySQL call on a full flow.
ITS ON DEVELOPING STAGE,DONT USE IT ON PRODUCTION.