1
0
mirror of synced 2026-04-19 23:08:39 +08:00

auto commit

This commit is contained in:
yitter
2023-03-12 18:09:33 +08:00
parent 536f436dfa
commit 61b9ea7fde
2 changed files with 101 additions and 47 deletions

View File

@@ -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,
})
}

View File

@@ -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)
}