1
0
mirror of synced 2025-12-17 02:28:12 +08:00

增加redis哨兵和集群模式的支持

This commit is contained in:
lifushen
2022-07-25 14:22:16 +08:00
parent a434e07c5d
commit 0b5f901097
2 changed files with 102 additions and 36 deletions

View File

@@ -19,27 +19,49 @@ func NextId() int64 {
return idgen.NextId() return idgen.NextId()
} }
// 注册一个 WorkerId会先注销所有本机已注册的记录 // RegisterOne 注册一个 WorkerId会先注销所有本机已注册的记录
// address: Redis连接地址单机模式示例127.0.0.1:6379哨兵/集群模式示例127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库示例1
// sentinelMasterName: Redis 哨兵模式下的服务名称示例mymaster
// maxWorkerId: WorkerId 最大值示例63
//export RegisterOne //export RegisterOne
func RegisterOne(ip *C.char, port int32, password *C.char, maxWorkerId int32) int32 { func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32) int32 {
return regworkerid.RegisterOne(C.GoString(ip), port, C.GoString(password), maxWorkerId) return regworkerid.RegisterOne(regworkerid.RegisterConf{
Address: C.GoString(address),
Password: C.GoString(password),
DB: db,
MasterName: C.GoString(sentinelMasterName),
MaxWorkerId: maxWorkerId,
})
} }
// 注册多个 WorkerId会先注销所有本机已注册的记录 // RegisterMany 注册多个 WorkerId会先注销所有本机已注册的记录
///export RegisterMany // address: Redis连接地址单机模式示例127.0.0.1:6379哨兵/集群模式示例127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
func RegisterMany(ip *C.char, port int32, password *C.char, maxWorkerId int32, totalCount int32) []int32 { // password: Redis连接密码
//values := regworkerid.RegisterMany(C.GoString(ip), port, C.GoString(password), maxWorkerId, totalCount) // db: Redis指定存储库示例1
//return (*C.int)(unsafe.Pointer(&values)) // sentinelMasterName: Redis 哨兵模式下的服务名称示例mymaster
return regworkerid.RegisterMany(C.GoString(ip), port, C.GoString(password), maxWorkerId, totalCount) // maxWorkerId: WorkerId 最大值示例63
// totalCount: 获取N个WorkerId示例5
//export RegisterMany
func RegisterMany(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32, totalCount 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,
})
} }
// 注销本机已注册的 WorkerId // UnRegister 注销本机已注册的 WorkerId
//export UnRegister //export UnRegister
func UnRegister() { func UnRegister() {
regworkerid.UnRegister() regworkerid.UnRegister()
} }
// 检查本地WorkerId是否有效0-有效,其它-无效) // Validate 检查本地WorkerId是否有效0-有效,其它-无效)
//export Validate //export Validate
func Validate(workerId int32) int32 { func Validate(workerId int32) int32 {
return regworkerid.Validate(workerId) return regworkerid.Validate(workerId)
@@ -70,13 +92,37 @@ func main() {
time.Sleep(time.Duration(1000) * time.Millisecond) time.Sleep(time.Duration(1000) * time.Millisecond)
} }
} else { } else {
workerIdList := regworkerid.RegisterMany("localhost", 6379, "", 4, 3)
for _, value := range workerIdList {
fmt.Println("注册的WorkerId:", value)
}
//var workerId = regworkerid.RegisterOne("localhost", 6379, "", 4) //// Redis单机模式下获取多个WorkerId
//fmt.Println("注册的WorkerId:", workerId) //workerIdList := regworkerid.RegisterMany(regworkerid.RegisterConf{
// Address: "127.0.0.1:6379",
// Password: "",
// DB: 0,
// MaxWorkerId: 4,
// TotalCount: 3,
//})
//for _, value := range workerIdList {
// fmt.Println("RegisterMany--注册的WorkerId:", value)
//}
// Redis单机模式下获取一个WorkerId
var workerId = regworkerid.RegisterOne(regworkerid.RegisterConf{
Address: "127.0.0.1:6379",
Password: "",
DB: 0,
MaxWorkerId: 4,
})
fmt.Println("RegisterOne--注册的WorkerId:", workerId)
//// Redis哨兵模式下获取一个WorkerId
//var workerId = regworkerid.RegisterOne(regworkerid.RegisterConf{
// //Address: "127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382",
// Password: "",
// DB: 0,
// MasterName: "mymaster", // 哨兵模式下的服务名称
// MaxWorkerId: 4,
//})
//fmt.Println("RegisterOne--注册的WorkerId:", workerId)
fmt.Println("end") fmt.Println("end")
time.Sleep(time.Duration(300) * time.Second) time.Sleep(time.Duration(300) * time.Second)

View File

@@ -5,11 +5,12 @@ import (
"fmt" "fmt"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
) )
var _client *redis.Client var _client redis.UniversalClient
var _ctx = context.Background() var _ctx = context.Background()
var _workerIdLock sync.Mutex var _workerIdLock sync.Mutex
@@ -25,11 +26,22 @@ var _MaxWorkerId int32 = 0 // 最大WorkerId值超过此值从0开
var _RedisConnString = "" var _RedisConnString = ""
var _RedisPassword = "" var _RedisPassword = ""
var _RedisDB = 0
var _RedisMasterName = ""
const _WorkerIdIndexKey string = "IdGen:WorkerId:Index" // redis 中的key const _WorkerIdIndexKey string = "IdGen:WorkerId:Index" // redis 中的key
const _WorkerIdValueKeyPrefix string = "IdGen:WorkerId:Value:" // redis 中的key const _WorkerIdValueKeyPrefix string = "IdGen:WorkerId:Value:" // redis 中的key
const _WorkerIdFlag = "Y" // IdGen:WorkerId:Value:xx 的值(将来可用 _token 替代) const _WorkerIdFlag = "Y" // IdGen:WorkerId:Value:xx 的值(将来可用 _token 替代)
const _Log = false // 是否输出日志 const _Log = false // 是否输出日志
type RegisterConf struct {
Address string // 注意:哨兵模式下,这里传入的是 Sentinel 节点,不是 Redis 节点
Password string
DB int
MasterName string // 注意:哨兵模式下,这里必须传入 Sentinel 服务名称
MaxWorkerId int32
TotalCount int32 // 注意:仅对 RegisterMany 生效
}
func Validate(workerId int32) int32 { func Validate(workerId int32) int32 {
for _, value := range _workerIdList { for _, value := range _workerIdList {
@@ -68,20 +80,24 @@ func autoUnRegister() {
} }
} }
func RegisterMany(ip string, port int32, password string, maxWorkerId int32, totalCount int32) []int32 { func RegisterMany(conf RegisterConf) []int32 {
if maxWorkerId < 0 { if conf.MaxWorkerId < 0 {
return []int32{-2} return []int32{-2}
} }
if totalCount < 1 { if conf.TotalCount < 1 {
return []int32{-1} return []int32{-1}
} else if conf.TotalCount == 0 {
conf.TotalCount = 1
} }
autoUnRegister() autoUnRegister()
_MaxWorkerId = maxWorkerId _MaxWorkerId = conf.MaxWorkerId
_RedisConnString = ip + ":" + strconv.Itoa(int(port)) _RedisConnString = conf.Address
_RedisPassword = password _RedisPassword = conf.Password
_RedisDB = conf.DB
_RedisMasterName = conf.MasterName
_client = newRedisClient() _client = newRedisClient()
if _client == nil { if _client == nil {
return []int32{-1} return []int32{-1}
@@ -102,7 +118,7 @@ func RegisterMany(ip string, port int32, password string, maxWorkerId int32, tot
//} //}
_lifeIndex++ _lifeIndex++
_workerIdList = make([]int32, totalCount) _workerIdList = make([]int32, conf.TotalCount)
for key := range _workerIdList { for key := range _workerIdList {
_workerIdList[key] = -1 // 全部初始化-1 _workerIdList[key] = -1 // 全部初始化-1
} }
@@ -125,16 +141,18 @@ func RegisterMany(ip string, port int32, password string, maxWorkerId int32, tot
return _workerIdList return _workerIdList
} }
func RegisterOne(ip string, port int32, password string, maxWorkerId int32) int32 { func RegisterOne(conf RegisterConf) int32 {
if maxWorkerId < 0 { if conf.MaxWorkerId < 0 {
return -2 return -2
} }
autoUnRegister() autoUnRegister()
_MaxWorkerId = maxWorkerId _MaxWorkerId = conf.MaxWorkerId
_RedisConnString = ip + ":" + strconv.Itoa(int(port)) _RedisConnString = conf.Address
_RedisPassword = password _RedisPassword = conf.Password
_RedisDB = conf.DB
_RedisMasterName = conf.MasterName
_loopCount = 0 _loopCount = 0
_client = newRedisClient() _client = newRedisClient()
if _client == nil { if _client == nil {
@@ -170,16 +188,18 @@ func register(lifeTime int) int32 {
return getNextWorkerId(lifeTime) return getNextWorkerId(lifeTime)
} }
func newRedisClient() *redis.Client { func newRedisClient() redis.UniversalClient {
return redis.NewClient(&redis.Options{ client := redis.NewUniversalClient(&redis.UniversalOptions{
Addr: _RedisConnString, Addrs: strings.Split(_RedisConnString, ","),
Password: _RedisPassword, Password: _RedisPassword,
DB: 0, DB: _RedisDB,
MasterName: _RedisMasterName,
//PoolSize: 1000, //PoolSize: 1000,
//ReadTimeout: time.Millisecond * time.Duration(100), //ReadTimeout: time.Millisecond * time.Duration(100),
//WriteTimeout: time.Millisecond * time.Duration(100), //WriteTimeout: time.Millisecond * time.Duration(100),
//IdleTimeout: time.Second * time.Duration(60), //IdleTimeout: time.Second * time.Duration(60),
}) })
return client
} }
func getNextWorkerId(lifeTime int) int32 { func getNextWorkerId(lifeTime int) int32 {