mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
1.MongoDB、Redis兼容集群模式
2.离线数据接口化访问
This commit is contained in:
@@ -2,6 +2,7 @@ package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"hk4e/common/config"
|
||||
"hk4e/pkg/logger"
|
||||
@@ -13,13 +14,15 @@ import (
|
||||
)
|
||||
|
||||
type Dao struct {
|
||||
mongo *mongo.Client
|
||||
db *mongo.Database
|
||||
redis *redis.Client
|
||||
mongo *mongo.Client
|
||||
db *mongo.Database
|
||||
redis *redis.Client
|
||||
redisCluster *redis.ClusterClient
|
||||
}
|
||||
|
||||
func NewDao() (r *Dao, err error) {
|
||||
r = new(Dao)
|
||||
|
||||
clientOptions := options.Client().ApplyURI(config.GetConfig().Database.Url).SetMinPoolSize(1).SetMaxPoolSize(10)
|
||||
client, err := mongo.Connect(context.TODO(), clientOptions)
|
||||
if err != nil {
|
||||
@@ -33,18 +36,37 @@ func NewDao() (r *Dao, err error) {
|
||||
}
|
||||
r.mongo = client
|
||||
r.db = client.Database("gs_hk4e")
|
||||
r.redis = redis.NewClient(&redis.Options{
|
||||
Addr: config.GetConfig().Redis.Addr,
|
||||
Password: config.GetConfig().Redis.Password,
|
||||
DB: 0,
|
||||
PoolSize: 10,
|
||||
MinIdleConns: 1,
|
||||
})
|
||||
err = r.redis.Ping(context.TODO()).Err()
|
||||
|
||||
r.redis = nil
|
||||
r.redisCluster = nil
|
||||
redisAddr := strings.ReplaceAll(config.GetConfig().Redis.Addr, "redis://", "")
|
||||
if strings.Contains(redisAddr, ",") {
|
||||
redisAddrList := strings.Split(redisAddr, ",")
|
||||
r.redisCluster = redis.NewClusterClient(&redis.ClusterOptions{
|
||||
Addrs: redisAddrList,
|
||||
Password: config.GetConfig().Redis.Password,
|
||||
PoolSize: 10,
|
||||
MinIdleConns: 1,
|
||||
})
|
||||
} else {
|
||||
r.redis = redis.NewClient(&redis.Options{
|
||||
Addr: redisAddr,
|
||||
Password: config.GetConfig().Redis.Password,
|
||||
DB: 0,
|
||||
PoolSize: 10,
|
||||
MinIdleConns: 1,
|
||||
})
|
||||
}
|
||||
if r.redisCluster != nil {
|
||||
err = r.redisCluster.Ping(context.TODO()).Err()
|
||||
} else {
|
||||
err = r.redis.Ping(context.TODO()).Err()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("redis ping error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -53,7 +75,11 @@ func (d *Dao) CloseDao() {
|
||||
if err != nil {
|
||||
logger.Error("mongo close error: %v", err)
|
||||
}
|
||||
err = d.redis.Close()
|
||||
if d.redisCluster != nil {
|
||||
err = d.redisCluster.Close()
|
||||
} else {
|
||||
err = d.redis.Close()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("redis close error: %v", err)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func (d *Dao) DeleteChatMsgList(idList []primitive.ObjectID) error {
|
||||
|
||||
func (d *Dao) UpdatePlayer(player *model.Player) error {
|
||||
db := d.db.Collection("player")
|
||||
_, err := db.UpdateOne(
|
||||
_, err := db.UpdateMany(
|
||||
context.TODO(),
|
||||
bson.D{{"PlayerID", player.PlayerID}},
|
||||
bson.D{{"$set", player}},
|
||||
@@ -129,7 +129,7 @@ func (d *Dao) UpdatePlayer(player *model.Player) error {
|
||||
|
||||
func (d *Dao) UpdateChatMsg(chatMsg *model.ChatMsg) error {
|
||||
db := d.db.Collection("chat_msg")
|
||||
_, err := db.UpdateOne(
|
||||
_, err := db.UpdateMany(
|
||||
context.TODO(),
|
||||
bson.D{{"_id", chatMsg.ID}},
|
||||
bson.D{{"$set", chatMsg}},
|
||||
@@ -147,7 +147,7 @@ func (d *Dao) UpdatePlayerList(playerList []*model.Player) error {
|
||||
db := d.db.Collection("player")
|
||||
modelOperateList := make([]mongo.WriteModel, 0)
|
||||
for _, player := range playerList {
|
||||
modelOperate := mongo.NewUpdateOneModel().SetFilter(bson.D{{"PlayerID", player.PlayerID}}).SetUpdate(bson.D{{"$set", player}})
|
||||
modelOperate := mongo.NewUpdateManyModel().SetFilter(bson.D{{"PlayerID", player.PlayerID}}).SetUpdate(bson.D{{"$set", player}})
|
||||
modelOperateList = append(modelOperateList, modelOperate)
|
||||
}
|
||||
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||
@@ -164,7 +164,7 @@ func (d *Dao) UpdateChatMsgList(chatMsgList []*model.ChatMsg) error {
|
||||
db := d.db.Collection("chat_msg")
|
||||
modelOperateList := make([]mongo.WriteModel, 0)
|
||||
for _, chatMsg := range chatMsgList {
|
||||
modelOperate := mongo.NewUpdateOneModel().SetFilter(bson.D{{"_id", chatMsg.ID}}).SetUpdate(bson.D{{"$set", chatMsg}})
|
||||
modelOperate := mongo.NewUpdateManyModel().SetFilter(bson.D{{"_id", chatMsg.ID}}).SetUpdate(bson.D{{"$set", chatMsg}})
|
||||
modelOperateList = append(modelOperateList, modelOperate)
|
||||
}
|
||||
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||
|
||||
@@ -30,7 +30,13 @@ func (d *Dao) GetRedisPlayerLockKey(userId uint32) string {
|
||||
// GetRedisPlayer 获取玩家数据
|
||||
func (d *Dao) GetRedisPlayer(userId uint32) *model.Player {
|
||||
startTime := time.Now().UnixNano()
|
||||
playerDataLz4, err := d.redis.Get(context.TODO(), d.GetRedisPlayerKey(userId)).Result()
|
||||
var playerDataLz4 = ""
|
||||
var err error = nil
|
||||
if d.redisCluster != nil {
|
||||
playerDataLz4, err = d.redisCluster.Get(context.TODO(), d.GetRedisPlayerKey(userId)).Result()
|
||||
} else {
|
||||
playerDataLz4, err = d.redis.Get(context.TODO(), d.GetRedisPlayerKey(userId)).Result()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("get player from redis error: %v", err)
|
||||
return nil
|
||||
@@ -90,7 +96,11 @@ func (d *Dao) SetRedisPlayer(player *model.Player) {
|
||||
logger.Debug("lz4 encode cost time: %v ns, before len: %v, after len: %v, ratio lz4/raw: %v",
|
||||
costTime, len(playerData), len(playerDataLz4), float64(len(playerDataLz4))/float64(len(playerData)))
|
||||
startTime = time.Now().UnixNano()
|
||||
err = d.redis.Set(context.TODO(), d.GetRedisPlayerKey(player.PlayerID), playerDataLz4, time.Hour*24*30).Err()
|
||||
if d.redisCluster != nil {
|
||||
err = d.redisCluster.Set(context.TODO(), d.GetRedisPlayerKey(player.PlayerID), playerDataLz4, time.Hour*24*30).Err()
|
||||
} else {
|
||||
err = d.redis.Set(context.TODO(), d.GetRedisPlayerKey(player.PlayerID), playerDataLz4, time.Hour*24*30).Err()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("set player to redis error: %v", err)
|
||||
return
|
||||
@@ -118,10 +128,19 @@ const (
|
||||
|
||||
// DistLock 加锁并返回是否成功
|
||||
func (d *Dao) DistLock(userId uint32) bool {
|
||||
result, err := d.redis.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
var result = false
|
||||
var err error = nil
|
||||
if d.redisCluster != nil {
|
||||
result, err = d.redisCluster.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
} else {
|
||||
result, err = d.redis.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("redis lock setnx error: %v", err)
|
||||
return false
|
||||
@@ -132,10 +151,19 @@ func (d *Dao) DistLock(userId uint32) bool {
|
||||
// DistLockSync 加锁同步阻塞直到成功或超时
|
||||
func (d *Dao) DistLockSync(userId uint32) bool {
|
||||
for i := 0; i < MaxLockRetryTimes; i++ {
|
||||
result, err := d.redis.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
var result = false
|
||||
var err error = nil
|
||||
if d.redisCluster != nil {
|
||||
result, err = d.redisCluster.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
} else {
|
||||
result, err = d.redis.SetNX(context.TODO(),
|
||||
d.GetRedisPlayerLockKey(userId),
|
||||
time.Now().UnixMilli(),
|
||||
time.Millisecond*time.Duration(MaxLockAliveTime)).Result()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("redis lock setnx error: %v", err)
|
||||
return false
|
||||
@@ -150,7 +178,13 @@ func (d *Dao) DistLockSync(userId uint32) bool {
|
||||
|
||||
// DistUnlock 解锁
|
||||
func (d *Dao) DistUnlock(userId uint32) {
|
||||
result, err := d.redis.Del(context.TODO(), d.GetRedisPlayerLockKey(userId)).Result()
|
||||
var result int64 = 0
|
||||
var err error = nil
|
||||
if d.redisCluster != nil {
|
||||
result, err = d.redisCluster.Del(context.TODO(), d.GetRedisPlayerLockKey(userId)).Result()
|
||||
} else {
|
||||
result, err = d.redis.Del(context.TODO(), d.GetRedisPlayerLockKey(userId)).Result()
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("redis lock del error: %v", err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user