应用集成平台服务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

465 lines
11 KiB

package redisController
import (
"appPlatform/overall/publicmethod"
"context"
"fmt"
"sort"
"strconv"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
)
/*
*
@ 作者: 秦东
@ 时间: 2023-11-13 14:27:45
@ 功能: 测试数据库链接
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) TestRedisLink(c *gin.Context) {
var redisConfig RedisConfig
err := c.ShouldBindJSON(&redisConfig)
if err != nil {
publicmethod.Result(10001, err, c)
return
}
if redisConfig.Ip == "" {
redisConfig.Ip = "127.0.0.1"
}
if redisConfig.Port == 0 {
redisConfig.Port = 6379
}
var redisDbConst RunOneRedis
redisDbConst.Ip = redisConfig.Ip
redisDbConst.Port = redisConfig.Port
redisDbConst.Pwd = redisConfig.Pwd
redisDbConst.DbName = 10
redisDb := redisDbConst.OpenRedis()
// pingLink, err := redisDb.Ping(context.Background()).Result()
_, err = redisDb.Ping(context.Background()).Result()
redisRunDb := InitRedis(redisDb)
redisCont, redisErr := redisRunDb.ConfigGet("databases")
// sendData := publicmethod.MapOut[string]()
// sendData["linkUrl"] = redisDb
// sendData["pingLink"] = pingLink
// sendData["err"] = err
// sendData["redisErr"] = redisErr
// sendData["redisCont"] = len(redisCont)
var sendInfo RedisLinkState
if err == nil {
sendInfo.IsTrue = 1
} else {
sendInfo.IsTrue = 2
publicmethod.Result(10001, sendInfo, c)
return
}
if redisErr != nil {
sendInfo.DbNumber = 16
} else {
sendInfo.DbNumber = 16
if len(redisCont) == 2 {
for k, v := range redisCont {
if k == 1 {
if val, isOk := v.(string); isOk {
sendInfo.DbNumber, _ = strconv.Atoi(val)
}
}
}
}
}
var redisListCont CountRedisKeyNumber
for i := 0; i < sendInfo.DbNumber; i++ {
syncSeting.Add(1)
go redisListCont.TallyRedisKeys(redisConfig.Ip, redisConfig.Pwd, redisConfig.Port, i)
}
syncSeting.Wait()
//根据维度序号排序
redisList := redisListCont.RedisList
sort.Slice(redisList, func(i, j int) bool {
return redisList[i].DbName < redisList[j].DbName
})
sendInfo.RedisList = redisList
// sendData["redisListCont"] = sendInfo
// sendData["redisListContlen"] = len(sendInfo)
publicmethod.Result(0, sendInfo, c)
}
/*
*
@ 作者: 秦东
@ 时间: 2023-11-14 10:19:13
@ 功能: 获取Redis有多少个数据库
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func GainRedisDbNumber(redisDb *redis.Client) (dbNumber int) {
redisRunDb := InitRedis(redisDb)
redisCont, redisErr := redisRunDb.ConfigGet("databases")
if redisErr != nil {
dbNumber = 16
} else {
dbNumber = 16
if len(redisCont) == 2 {
for k, v := range redisCont {
if k == 1 {
if val, isOk := v.(string); isOk {
dbNumber, _ = strconv.Atoi(val)
}
}
}
}
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2023-11-13 16:32:45
@ 功能: 计算Redis数据库键个数
@ 参数
#ip Redis数据库地址
#port 端口
#pwd 密码
#dbId 数据库值
@ 返回值
#
@ 方法原型
#
*/
func (c *CountRedisKeyNumber) TallyRedisKeys(ip, pwd string, port, dbId int) {
var redisDbConst RunOneRedis
redisDbConst.Ip = ip
redisDbConst.Port = port
redisDbConst.Pwd = pwd
redisDbConst.DbName = dbId
redisDb := redisDbConst.OpenRedis()
redisRunDb := InitRedis(redisDb)
val, err := redisRunDb.Keys("*")
// fmt.Printf("%v---->%v\n", dbId, val)
if err == nil {
var redisInfo RedisKeyNumber
redisInfo.DbName = dbId
redisInfo.DbNumber = len(val)
c.RedisList = append(c.RedisList, redisInfo)
}
defer syncSeting.Done()
}
/*
*
@ 作者: 秦东
@ 时间: 2023-11-13 16:11:18
@ 功能: 打开Redis
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (r *RunOneRedis) OpenRedis() (redisDb *redis.Client) {
linkUrl := fmt.Sprintf("%v:%v", r.Ip, r.Port)
redisDb = redis.NewClient(&redis.Options{
Addr: linkUrl,
Password: r.Pwd,
DB: r.DbName,
})
return
}
/*
*
@ 作者: 秦东
@ 时间: 2023-11-14 08:04:08
@ 功能: 迁移数据库
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) MoveOldRedisToNewRedis(c *gin.Context) {
// var callBalackMsg MoveRedisMsg
var requestData MoveRedis
err := c.ShouldBindJSON(&requestData)
if err != nil {
publicmethod.Result(10001, err, c)
return
}
if requestData.OriginRedis.State != 1 || requestData.TargetRedis.State != 1 {
publicmethod.Result(10001, err, c, "请先测试源Redis与目标Redis是否链接成功!")
return
}
if requestData.OriginRedis.Ip == "" || requestData.TargetRedis.Ip == "" {
publicmethod.Result(10001, err, c, "请检查源RedisIP与目标RedisIP是否已填写!")
return
}
if requestData.OriginRedis.Port == 0 {
requestData.OriginRedis.Port = 6379
}
if requestData.TargetRedis.Port == 0 {
requestData.TargetRedis.Port = 6379
}
// //源Redis链接
var redisDbOriginConst RunOneRedis
redisDbOriginConst.Ip = requestData.OriginRedis.Ip
redisDbOriginConst.Port = requestData.OriginRedis.Port
redisDbOriginConst.Pwd = requestData.OriginRedis.Pwd
redisDbOriginConst.DbName = 0
redisDbOrigin := redisDbOriginConst.OpenRedis()
_, err = redisDbOrigin.Ping(context.Background()).Result()
if err != nil {
publicmethod.Result(10001, err, c, "源Redis链接失败!")
return
}
// //目标Redis链接
// var redisDbTargetConst RunOneRedis
// redisDbTargetConst.Ip = requestData.TargetRedis.Ip
// redisDbTargetConst.Port = requestData.TargetRedis.Port
// redisDbTargetConst.Pwd = requestData.TargetRedis.Pwd
// redisDbTargetConst.DbName = 10
// redisDbTarget := redisDbTargetConst.OpenRedis()
// _, err = redisDbTarget.Ping(context.Background()).Result()
// if err != nil {
// publicmethod.Result(10001, err, c, "目标Redis链接失败!")
// return
// }
var redisMsg NewCopyOldRedisInfo
if len(requestData.DbList) > 0 {
for _, v := range requestData.DbList {
syncSeting.Add(1)
go redisMsg.NewsMoveOldRedis(requestData.OriginRedis, requestData.TargetRedis, v)
}
} else {
dbNum := GainRedisDbNumber(redisDbOrigin)
for i := 0; i < dbNum; i++ {
syncSeting.Add(1)
go redisMsg.NewsMoveOldRedis(requestData.OriginRedis, requestData.TargetRedis, i)
}
}
syncSeting.Wait()
redisList := redisMsg.MsgList
sort.Slice(redisList, func(i, j int) bool {
return redisList[i].DbName < redisList[j].DbName
})
publicmethod.Result(0, redisList, c)
}
/*
*
@ 作者: 秦东
@ 时间: 2023-11-14 08:30:52
@ 功能: 数据迁移
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (n *NewCopyOldRedisInfo) NewsMoveOldRedis(oldRedis, newRedis RedisLink, dbName int) {
// fmt.Printf("dbName--->%v\n", dbName)
var msgCont MoveRedisMsg
msgCont.DbName = dbName
var redisDbOriginConst RunOneRedis
redisDbOriginConst.Ip = oldRedis.Ip
redisDbOriginConst.Port = oldRedis.Port
redisDbOriginConst.Pwd = oldRedis.Pwd
redisDbOriginConst.DbName = dbName
redisDbOrigin := redisDbOriginConst.OpenRedis()
_, err := redisDbOrigin.Ping(context.Background()).Result()
if err == nil {
//目标Redis链接
var redisDbTargetConst RunOneRedis
redisDbTargetConst.Ip = newRedis.Ip
redisDbTargetConst.Port = newRedis.Port
redisDbTargetConst.Pwd = newRedis.Pwd
redisDbTargetConst.DbName = dbName
redisDbTarget := redisDbTargetConst.OpenRedis()
_, err = redisDbTarget.Ping(context.Background()).Result()
if err == nil {
oldRunDb := InitRedis(redisDbOrigin)
val, err := oldRunDb.Keys("*")
if err != nil {
var keyMsg MsgListInfo
keyMsg.Keys = "源数据库"
keyMsg.State = 2
keyMsg.Msg = err
msgCont.MsgList = append(msgCont.MsgList, keyMsg)
} else {
if len(val) > 1 {
newRunDb := InitRedis(redisDbTarget)
for _, v := range val {
var keyMsg MsgListInfo
keyMsg.Keys = v
vInfo, vErr := oldRunDb.KeyType(v)
// fmt.Printf("%v: %v\n", v, vInfo)
if vErr == nil {
switch vInfo {
case "string": //字符串
_, oldVal := oldRunDb.Get(v)
oldTTl, _ := oldRunDb.TTl(v)
if oldTTl < 0 {
oldTTl = 0
}
keyMsg.State = 1
newRunDb.SetRedisTime(oldTTl)
newRunDb.Set(v, oldVal)
keyMsg.Msg = "迁移完成!"
// fmt.Printf("%v:-------------->1--->%v--->%v--->%v\n", v, oldTTl, oldTTl < 0, oldVal)
case "list": //列表
oldVal, oldErr := oldRunDb.Lrange(v, 0, -1)
if oldErr == nil {
oldTTl, _ := oldRunDb.TTl(v)
if oldTTl < 0 {
oldTTl = 0
}
newRunDb.SetRedisTime(oldTTl)
for _, ov := range oldVal {
newRunDb.Rpushx(v, ov)
}
keyMsg.Msg = "迁移完成!"
keyMsg.State = 1
} else {
keyMsg.Msg = oldErr
keyMsg.State = 2
}
// fmt.Printf("%v:-------------->2\n", v)
case "set": //集合
oldVal, isTrue := oldRunDb.Smembers(v)
if isTrue == nil {
oldTTl, _ := oldRunDb.TTl(v)
if oldTTl < 0 {
oldTTl = 0
}
newRunDb.SetRedisTime(oldTTl)
newRunDb.Sadd(v, oldVal)
keyMsg.Msg = "迁移完成!"
keyMsg.State = 1
} else {
keyMsg.Msg = "键不存在!"
keyMsg.State = 2
}
// fmt.Printf("%v:-------------->3\n", v)
case "zset": //有序集
oldVal, isTrue := oldRunDb.Zrange(v, 0, -1)
if isTrue == nil {
oldTTl, _ := oldRunDb.TTl(v)
if oldTTl < 0 {
oldTTl = 0
}
newRunDb.SetRedisTime(oldTTl)
newRunDb.Zadd(v, oldVal)
keyMsg.Msg = "迁移完成!"
keyMsg.State = 1
} else {
keyMsg.Msg = "键不存在!"
keyMsg.State = 2
}
// fmt.Printf("%v:-------------->4\n", v)
case "hash": //哈希表
oldVal, isTrue := oldRunDb.HashGetAll(v)
if isTrue {
oldTTl, _ := oldRunDb.TTl(v)
if oldTTl < 0 {
oldTTl = 0
}
newRunDb.SetRedisTime(oldTTl)
newVal := publicmethod.MapOut[string]()
for ni, nv := range oldVal {
newVal[ni] = nv
}
newRunDb.HashMsetAdd(v, newVal)
keyMsg.Msg = "迁移完成!"
keyMsg.State = 1
} else {
keyMsg.Msg = "键不存在!"
keyMsg.State = 2
}
// fmt.Printf("%v:-------------->5\n", v)
default:
keyMsg.Msg = "键不存在!"
keyMsg.State = 2
// fmt.Printf("%v:-------------->6\n", v)
}
} else {
keyMsg.Msg = vErr
keyMsg.State = 2
}
msgCont.MsgList = append(msgCont.MsgList, keyMsg)
}
} else {
var keyMsg MsgListInfo
keyMsg.Keys = "源数据库"
keyMsg.Msg = "没有要迁移的数据!"
keyMsg.State = 2
msgCont.MsgList = append(msgCont.MsgList, keyMsg)
}
}
} else {
var keyMsg MsgListInfo
keyMsg.Keys = "目标数据库"
keyMsg.Msg = err
keyMsg.State = 2
msgCont.MsgList = append(msgCont.MsgList, keyMsg)
}
} else {
var keyMsg MsgListInfo
keyMsg.Keys = "源数据库"
keyMsg.Msg = err
keyMsg.State = 2
msgCont.MsgList = append(msgCont.MsgList, keyMsg)
}
n.MsgList = append(n.MsgList, msgCont)
defer syncSeting.Done()
}