auto commit
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
func main() {
|
||||
|
||||
//address := "192.168.1.207:6379"
|
||||
address := "127.0.0.1:6379"
|
||||
password := ""
|
||||
masterName := ""
|
||||
@@ -18,12 +19,12 @@ func main() {
|
||||
passChar := C.CString(password)
|
||||
masterNameChar := C.CString(masterName)
|
||||
|
||||
workerIdList := RegisterMany(addrChar, passChar, 4, masterNameChar, 3, 5)
|
||||
workerIdList := RegisterMany(addrChar, passChar, 4, masterNameChar, 31, 60, 20, 15)
|
||||
for _, value := range workerIdList {
|
||||
fmt.Println("注册的WorkerId:", value)
|
||||
}
|
||||
|
||||
id := RegisterOne(addrChar, passChar, 4, masterNameChar, 0)
|
||||
id := RegisterOne(addrChar, passChar, 4, masterNameChar, 31, 60, 15)
|
||||
fmt.Println("注册的WorkerId:", id)
|
||||
|
||||
fmt.Println("end")
|
||||
@@ -36,14 +37,18 @@ func main() {
|
||||
// db: Redis指定存储库,示例:1
|
||||
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster,非哨兵模式传入空字符串即可
|
||||
// maxWorkerId: WorkerId 最大值,示例:63
|
||||
// minWorkerId: WorkerId 最小值,示例:30
|
||||
// lifeTimeSeconds: WorkerId缓存时长(秒,3的倍数)
|
||||
//export RegisterOne
|
||||
func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32) int32 {
|
||||
func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *C.char, minWorkerId int32, maxWorkerId int32, lifeTimeSeconds int32) int32 {
|
||||
return regworkerid.RegisterOne(regworkerid.RegisterConf{
|
||||
Address: C.GoString(address),
|
||||
Password: C.GoString(password),
|
||||
DB: db,
|
||||
MasterName: C.GoString(sentinelMasterName),
|
||||
MaxWorkerId: maxWorkerId,
|
||||
Address: C.GoString(address),
|
||||
Password: C.GoString(password),
|
||||
DB: db,
|
||||
MasterName: C.GoString(sentinelMasterName),
|
||||
MinWorkerId: minWorkerId,
|
||||
MaxWorkerId: maxWorkerId,
|
||||
LifeTimeSeconds: lifeTimeSeconds,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,16 +58,20 @@ func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *
|
||||
// db: Redis指定存储库,示例:1
|
||||
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster,非哨兵模式传入空字符串即可
|
||||
// maxWorkerId: WorkerId 最大值,示例:63
|
||||
// minWorkerId: WorkerId 最小值,示例:30
|
||||
// totalCount: 获取N个WorkerId,示例:5
|
||||
// lifeTimeSeconds: WorkerId缓存时长(秒,3的倍数)
|
||||
//export RegisterMany
|
||||
func RegisterMany(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32, totalCount int32) []int32 {
|
||||
func RegisterMany(address *C.char, password *C.char, db int, sentinelMasterName *C.char, minWorkerId int32, maxWorkerId int32, totalCount int32, lifeTimeSeconds int32) []int32 {
|
||||
return regworkerid.RegisterMany(regworkerid.RegisterConf{
|
||||
Address: C.GoString(address),
|
||||
Password: C.GoString(password),
|
||||
DB: db,
|
||||
MasterName: C.GoString(sentinelMasterName),
|
||||
MaxWorkerId: maxWorkerId,
|
||||
TotalCount: totalCount,
|
||||
Address: C.GoString(address),
|
||||
Password: C.GoString(password),
|
||||
DB: db,
|
||||
MasterName: C.GoString(sentinelMasterName),
|
||||
MinWorkerId: minWorkerId,
|
||||
MaxWorkerId: maxWorkerId,
|
||||
TotalCount: totalCount,
|
||||
LifeTimeSeconds: lifeTimeSeconds,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ package regworkerid
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
var _client redis.UniversalClient
|
||||
@@ -15,32 +16,35 @@ var _ctx = context.Background()
|
||||
var _workerIdLock sync.Mutex
|
||||
|
||||
var _workerIdList []int32 // 当前已注册的WorkerId
|
||||
var _loopCount = 0 // 循环数量
|
||||
var _lifeIndex = -1 // WorkerId本地生命时序(本地多次注册时,生命时序会不同)
|
||||
var _token = -1 // WorkerId远程注册时用的token,将存储在 IdGen:WorkerId:Value:xx 的值中(本功能暂未启用)
|
||||
var _loopCount int32 = 0 // 循环数量
|
||||
var _lifeIndex int32 = -1 // WorkerId本地生命时序(本地多次注册时,生命时序会不同)
|
||||
var _token int32 = -1 // WorkerId远程注册时用的token,将存储在 IdGen:WorkerId:Value:xx 的值中(本功能暂未启用)
|
||||
|
||||
var _WorkerIdLifeTimeSeconds = 15 // IdGen:WorkerId:Value:xx 的值在 redis 中的有效期(单位秒,最好是3的整数倍)
|
||||
var _MaxLoopCount = 10 // 最大循环次数(无可用WorkerId时循环查找)
|
||||
var _SleepMillisecondEveryLoop = 200 // 每次循环后,暂停时间
|
||||
var _MaxWorkerId int32 = 0 // 最大WorkerId值,超过此值从0开始
|
||||
var _WorkerIdLifeTimeSeconds int32 = 15 // IdGen:WorkerId:Value:xx 的值在 redis 中的有效期(单位秒,最好是3的整数倍)
|
||||
var _MaxLoopCount int32 = 20 // 最大循环次数(无可用WorkerId时循环查找)
|
||||
var _SleepMillisecondEveryLoop int32 = 200 // 每次循环后,暂停时间
|
||||
var _MaxWorkerId int32 = 0 // 最大WorkerId值,超过此值从_MinWorkerId开始
|
||||
var _MinWorkerId int32 = 0 // 最小WorkerId值
|
||||
|
||||
var _RedisConnString = ""
|
||||
var _RedisPassword = ""
|
||||
var _RedisDB = 0
|
||||
var _RedisDB int = 0
|
||||
var _RedisMasterName = ""
|
||||
|
||||
const _WorkerIdIndexKey string = "IdGen:WorkerId:Index" // redis 中的key
|
||||
const _WorkerIdValueKeyPrefix string = "IdGen:WorkerId:Value:" // redis 中的key
|
||||
const _WorkerIdFlag = "Y" // IdGen:WorkerId:Value:xx 的值(将来可用 _token 替代)
|
||||
const _Log = false // 是否输出日志
|
||||
var _WorkerIdIndexKey string = "IdGen:WorkerId:Index" // redis 中的key
|
||||
var _WorkerIdValueKeyPrefix string = "IdGen:WorkerId:Value:" // redis 中的key
|
||||
var _WorkerIdFlag = "Y" // IdGen:WorkerId:Value:xx 的值(将来可用 _token 替代)
|
||||
var _Log = false // 是否输出日志
|
||||
|
||||
type RegisterConf struct {
|
||||
Address string // 注意:哨兵模式下,这里传入的是 Sentinel 节点,不是 Redis 节点
|
||||
Password string
|
||||
DB int
|
||||
MasterName string // 注意:哨兵模式下,这里必须传入 Sentinel 服务名称
|
||||
MaxWorkerId int32
|
||||
TotalCount int32 // 注意:仅对 RegisterMany 生效
|
||||
Address string // 注意:哨兵模式下,这里传入的是 Sentinel 节点,不是 Redis 节点
|
||||
Password string
|
||||
DB int
|
||||
MasterName string // 注意:哨兵模式下,这里必须传入 Sentinel 服务名称
|
||||
MaxWorkerId int32
|
||||
MinWorkerId int32
|
||||
TotalCount int32 // 注意:仅对 RegisterMany 生效
|
||||
LifeTimeSeconds int32
|
||||
}
|
||||
|
||||
func Validate(workerId int32) int32 {
|
||||
@@ -60,14 +64,30 @@ func Validate(workerId int32) int32 {
|
||||
}
|
||||
|
||||
func UnRegister() {
|
||||
_client = newRedisClient()
|
||||
if _client == nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if _client != nil {
|
||||
_ = _client.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
myUnRegister()
|
||||
}
|
||||
|
||||
func myUnRegister() {
|
||||
_workerIdLock.Lock()
|
||||
|
||||
// ToDo:在清除本地WorkerId之后,要删除redis键,并清除定时任务
|
||||
_lifeIndex = -1
|
||||
for _, value := range _workerIdList {
|
||||
if value > -1 {
|
||||
_client.Del(_ctx, _WorkerIdValueKeyPrefix+strconv.Itoa(int(value)))
|
||||
}
|
||||
}
|
||||
|
||||
_workerIdList = []int32{}
|
||||
|
||||
_workerIdLock.Unlock()
|
||||
@@ -76,12 +96,13 @@ func UnRegister() {
|
||||
func autoUnRegister() {
|
||||
// 如果当前已注册过 WorkerId,则先注销,并终止先前的自动续期线程
|
||||
if len(_workerIdList) > 0 {
|
||||
UnRegister()
|
||||
//UnRegister()
|
||||
myUnRegister()
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterMany(conf RegisterConf) []int32 {
|
||||
if conf.MaxWorkerId < 0 {
|
||||
if conf.MaxWorkerId < 0 || conf.MinWorkerId > conf.MaxWorkerId {
|
||||
return []int32{-2}
|
||||
}
|
||||
|
||||
@@ -91,13 +112,14 @@ func RegisterMany(conf RegisterConf) []int32 {
|
||||
conf.TotalCount = 1
|
||||
}
|
||||
|
||||
autoUnRegister()
|
||||
|
||||
_MaxWorkerId = conf.MaxWorkerId
|
||||
_MinWorkerId = conf.MinWorkerId
|
||||
_RedisConnString = conf.Address
|
||||
_RedisPassword = conf.Password
|
||||
_RedisDB = conf.DB
|
||||
_RedisMasterName = conf.MasterName
|
||||
_WorkerIdLifeTimeSeconds = conf.LifeTimeSeconds
|
||||
|
||||
_client = newRedisClient()
|
||||
if _client == nil {
|
||||
return []int32{-1}
|
||||
@@ -107,6 +129,9 @@ func RegisterMany(conf RegisterConf) []int32 {
|
||||
_ = _client.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
autoUnRegister()
|
||||
|
||||
//_, err := _client.Ping(_ctx).Result()
|
||||
//if err != nil {
|
||||
// //panic("init redis error")
|
||||
@@ -142,18 +167,19 @@ func RegisterMany(conf RegisterConf) []int32 {
|
||||
}
|
||||
|
||||
func RegisterOne(conf RegisterConf) int32 {
|
||||
if conf.MaxWorkerId < 0 {
|
||||
if conf.MaxWorkerId < 0 || conf.MinWorkerId > conf.MaxWorkerId {
|
||||
return -2
|
||||
}
|
||||
|
||||
autoUnRegister()
|
||||
|
||||
_MaxWorkerId = conf.MaxWorkerId
|
||||
_MinWorkerId = conf.MinWorkerId
|
||||
_RedisConnString = conf.Address
|
||||
_RedisPassword = conf.Password
|
||||
_RedisDB = conf.DB
|
||||
_RedisMasterName = conf.MasterName
|
||||
_WorkerIdLifeTimeSeconds = conf.LifeTimeSeconds
|
||||
_loopCount = 0
|
||||
|
||||
_client = newRedisClient()
|
||||
if _client == nil {
|
||||
return -3
|
||||
@@ -173,6 +199,8 @@ func RegisterOne(conf RegisterConf) int32 {
|
||||
// }
|
||||
//}
|
||||
|
||||
autoUnRegister()
|
||||
|
||||
_lifeIndex++
|
||||
var id = register(_lifeIndex)
|
||||
if id > -1 {
|
||||
@@ -183,7 +211,7 @@ func RegisterOne(conf RegisterConf) int32 {
|
||||
return id
|
||||
}
|
||||
|
||||
func register(lifeTime int) int32 {
|
||||
func register(lifeTime int32) int32 {
|
||||
_loopCount = 0
|
||||
return getNextWorkerId(lifeTime)
|
||||
}
|
||||
@@ -202,7 +230,7 @@ func newRedisClient() redis.UniversalClient {
|
||||
return client
|
||||
}
|
||||
|
||||
func getNextWorkerId(lifeTime int) int32 {
|
||||
func getNextWorkerId(lifeTime int32) int32 {
|
||||
// 获取当前 WorkerIdIndex
|
||||
r, err := _client.Incr(_ctx, _WorkerIdIndexKey).Result()
|
||||
if err != nil {
|
||||
@@ -210,6 +238,13 @@ func getNextWorkerId(lifeTime int) int32 {
|
||||
}
|
||||
|
||||
candidateId := int32(r)
|
||||
|
||||
// 设置最小值
|
||||
if candidateId < _MinWorkerId {
|
||||
candidateId = _MinWorkerId
|
||||
setWorkerIdIndex(_MinWorkerId)
|
||||
}
|
||||
|
||||
if _Log {
|
||||
fmt.Println("Begin candidateId:" + strconv.Itoa(int(candidateId)))
|
||||
}
|
||||
@@ -218,7 +253,8 @@ func getNextWorkerId(lifeTime int) int32 {
|
||||
if candidateId > _MaxWorkerId {
|
||||
if canReset() {
|
||||
// 当前应用获得重置 WorkerIdIndex 的权限
|
||||
setWorkerIdIndex(-1)
|
||||
//setWorkerIdIndex(-1)
|
||||
setWorkerIdIndex(_MinWorkerId - 1)
|
||||
endReset() // 此步有可能不被执行?
|
||||
_loopCount++
|
||||
|
||||
@@ -276,7 +312,7 @@ func getNextWorkerId(lifeTime int) int32 {
|
||||
}
|
||||
}
|
||||
|
||||
func extendLifeTime(lifeIndex int) {
|
||||
func extendLifeTime(lifeIndex int32) {
|
||||
// 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 _WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime)
|
||||
var myLifeIndex = lifeIndex
|
||||
|
||||
@@ -288,6 +324,7 @@ func extendLifeTime(lifeIndex int) {
|
||||
_workerIdLock.Lock()
|
||||
|
||||
// 如果临时变量 myLifeIndex 不等于 全局变量 _lifeIndex,表明全局状态被修改,当前线程可终止,不应继续操作 redis
|
||||
// 还应主动释放 redis 键值缓存
|
||||
if myLifeIndex != _lifeIndex {
|
||||
break
|
||||
}
|
||||
@@ -308,7 +345,7 @@ func extendLifeTime(lifeIndex int) {
|
||||
}
|
||||
}
|
||||
|
||||
func extendWorkerIdLifeTime(lifeIndex int, workerId int32) {
|
||||
func extendWorkerIdLifeTime(lifeIndex int32, workerId int32) {
|
||||
var myLifeIndex = lifeIndex
|
||||
var myWorkerId = workerId
|
||||
|
||||
@@ -344,11 +381,19 @@ func get(key string) (string, bool) {
|
||||
return r, true
|
||||
}
|
||||
|
||||
func del(key string) (int64, bool) {
|
||||
r, err := _client.Del(_ctx, key).Result()
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
|
||||
func set(key string, val string, expTime int32) {
|
||||
_client.Set(_ctx, key, val, time.Duration(expTime)*time.Second)
|
||||
}
|
||||
|
||||
func setWorkerIdIndex(val int) {
|
||||
func setWorkerIdIndex(val int32) {
|
||||
_client.Set(_ctx, _WorkerIdIndexKey, val, 0)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user