增加redis哨兵和集群模式的支持pull/19/MERGE
@@ -19,27 +19,49 @@ func NextId() int64 { | |||
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 | |||
func RegisterOne(ip *C.char, port int32, password *C.char, maxWorkerId int32) int32 { | |||
return regworkerid.RegisterOne(C.GoString(ip), port, C.GoString(password), maxWorkerId) | |||
func RegisterOne(address *C.char, password *C.char, db int, sentinelMasterName *C.char, maxWorkerId int32) int32 { | |||
return regworkerid.RegisterOne(regworkerid.RegisterConf{ | |||
Address: C.GoString(address), | |||
Password: C.GoString(password), | |||
DB: db, | |||
MasterName: C.GoString(sentinelMasterName), | |||
MaxWorkerId: maxWorkerId, | |||
}) | |||
} | |||
// 注册多个 WorkerId,会先注销所有本机已注册的记录 | |||
///export RegisterMany | |||
func RegisterMany(ip *C.char, port int32, password *C.char, maxWorkerId int32, totalCount int32) []int32 { | |||
//values := regworkerid.RegisterMany(C.GoString(ip), port, C.GoString(password), maxWorkerId, totalCount) | |||
//return (*C.int)(unsafe.Pointer(&values)) | |||
return regworkerid.RegisterMany(C.GoString(ip), port, C.GoString(password), maxWorkerId, totalCount) | |||
// RegisterMany 注册多个 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 | |||
// 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 | |||
func UnRegister() { | |||
regworkerid.UnRegister() | |||
} | |||
// 检查本地WorkerId是否有效(0-有效,其它-无效) | |||
// Validate 检查本地WorkerId是否有效(0-有效,其它-无效) | |||
//export Validate | |||
func Validate(workerId int32) int32 { | |||
return regworkerid.Validate(workerId) | |||
@@ -70,13 +92,37 @@ func main() { | |||
time.Sleep(time.Duration(1000) * time.Millisecond) | |||
} | |||
} else { | |||
workerIdList := regworkerid.RegisterMany("localhost", 6379, "", 4, 3) | |||
for _, value := range workerIdList { | |||
fmt.Println("注册的WorkerId:", value) | |||
} | |||
//var workerId = regworkerid.RegisterOne("localhost", 6379, "", 4) | |||
//fmt.Println("注册的WorkerId:", workerId) | |||
//// Redis单机模式下,获取多个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") | |||
time.Sleep(time.Duration(300) * time.Second) | |||
@@ -5,11 +5,12 @@ import ( | |||
"fmt" | |||
"github.com/go-redis/redis/v8" | |||
"strconv" | |||
"strings" | |||
"sync" | |||
"time" | |||
) | |||
var _client *redis.Client | |||
var _client redis.UniversalClient | |||
var _ctx = context.Background() | |||
var _workerIdLock sync.Mutex | |||
@@ -25,11 +26,22 @@ var _MaxWorkerId int32 = 0 // 最大WorkerId值,超过此值从0开 | |||
var _RedisConnString = "" | |||
var _RedisPassword = "" | |||
var _RedisDB = 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 // 是否输出日志 | |||
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 { | |||
for _, value := range _workerIdList { | |||
@@ -68,20 +80,24 @@ func autoUnRegister() { | |||
} | |||
} | |||
func RegisterMany(ip string, port int32, password string, maxWorkerId int32, totalCount int32) []int32 { | |||
if maxWorkerId < 0 { | |||
func RegisterMany(conf RegisterConf) []int32 { | |||
if conf.MaxWorkerId < 0 { | |||
return []int32{-2} | |||
} | |||
if totalCount < 1 { | |||
if conf.TotalCount < 1 { | |||
return []int32{-1} | |||
} else if conf.TotalCount == 0 { | |||
conf.TotalCount = 1 | |||
} | |||
autoUnRegister() | |||
_MaxWorkerId = maxWorkerId | |||
_RedisConnString = ip + ":" + strconv.Itoa(int(port)) | |||
_RedisPassword = password | |||
_MaxWorkerId = conf.MaxWorkerId | |||
_RedisConnString = conf.Address | |||
_RedisPassword = conf.Password | |||
_RedisDB = conf.DB | |||
_RedisMasterName = conf.MasterName | |||
_client = newRedisClient() | |||
if _client == nil { | |||
return []int32{-1} | |||
@@ -102,7 +118,7 @@ func RegisterMany(ip string, port int32, password string, maxWorkerId int32, tot | |||
//} | |||
_lifeIndex++ | |||
_workerIdList = make([]int32, totalCount) | |||
_workerIdList = make([]int32, conf.TotalCount) | |||
for key := range _workerIdList { | |||
_workerIdList[key] = -1 // 全部初始化-1 | |||
} | |||
@@ -125,16 +141,18 @@ func RegisterMany(ip string, port int32, password string, maxWorkerId int32, tot | |||
return _workerIdList | |||
} | |||
func RegisterOne(ip string, port int32, password string, maxWorkerId int32) int32 { | |||
if maxWorkerId < 0 { | |||
func RegisterOne(conf RegisterConf) int32 { | |||
if conf.MaxWorkerId < 0 { | |||
return -2 | |||
} | |||
autoUnRegister() | |||
_MaxWorkerId = maxWorkerId | |||
_RedisConnString = ip + ":" + strconv.Itoa(int(port)) | |||
_RedisPassword = password | |||
_MaxWorkerId = conf.MaxWorkerId | |||
_RedisConnString = conf.Address | |||
_RedisPassword = conf.Password | |||
_RedisDB = conf.DB | |||
_RedisMasterName = conf.MasterName | |||
_loopCount = 0 | |||
_client = newRedisClient() | |||
if _client == nil { | |||
@@ -170,16 +188,18 @@ func register(lifeTime int) int32 { | |||
return getNextWorkerId(lifeTime) | |||
} | |||
func newRedisClient() *redis.Client { | |||
return redis.NewClient(&redis.Options{ | |||
Addr: _RedisConnString, | |||
Password: _RedisPassword, | |||
DB: 0, | |||
func newRedisClient() redis.UniversalClient { | |||
client := redis.NewUniversalClient(&redis.UniversalOptions{ | |||
Addrs: strings.Split(_RedisConnString, ","), | |||
Password: _RedisPassword, | |||
DB: _RedisDB, | |||
MasterName: _RedisMasterName, | |||
//PoolSize: 1000, | |||
//ReadTimeout: time.Millisecond * time.Duration(100), | |||
//WriteTimeout: time.Millisecond * time.Duration(100), | |||
//IdleTimeout: time.Second * time.Duration(60), | |||
}) | |||
return client | |||
} | |||
func getNextWorkerId(lifeTime int) int32 { | |||