feat(cache): 优化缓存系统并重构数据库连接管理

- 将Redis连接方式改为连接池模式,提升连接复用效率
- 修复缓存注释错误,统一标识数据库缓存逻辑
- 添加数据检索结果非空验证,避免空指针异常
- 在数据库操作中添加读写锁保护,确保并发安全性
- 实现数据库查询和执行操作的重试机制,增强稳定性
- 更新配置文件中的缓存和数据库设置,优化缓存策略
- 重构README文档,补充框架特性和性能测试数据
- 添加示例路由配置,完善快速入门指南
This commit is contained in:
2026-01-22 04:36:52 +08:00
parent 7843f7e8d6
commit 40f6783036
16 changed files with 2991 additions and 511 deletions
+87 -67
View File
@@ -4,6 +4,7 @@ import (
. "code.hoteas.com/golang/hotime/common"
"github.com/garyburd/redigo/redis"
"strings"
"sync"
"time"
)
@@ -14,10 +15,11 @@ type CacheRedis struct {
Host string
Pwd string
Port int64
conn redis.Conn
pool *redis.Pool
tag int64
ContextBase
*Error
initOnce sync.Once
}
func (that *CacheRedis) GetError() *Error {
@@ -39,83 +41,112 @@ func (that *CacheRedis) GetTag() int64 {
return that.tag
}
func (that *CacheRedis) reCon() bool {
var err error
that.conn, err = redis.Dial("tcp", that.Host+":"+ObjToStr(that.Port))
if err != nil {
that.conn = nil
that.Error.SetError(err)
return false
}
if that.Pwd != "" {
_, err = that.conn.Do("AUTH", that.Pwd)
if err != nil {
that.conn = nil
that.Error.SetError(err)
return false
// initPool 初始化连接池(只执行一次)
func (that *CacheRedis) initPool() {
that.initOnce.Do(func() {
that.pool = &redis.Pool{
MaxIdle: 10, // 最大空闲连接数
MaxActive: 100, // 最大活跃连接数,0表示无限制
IdleTimeout: 5 * time.Minute, // 空闲连接超时时间
Wait: true, // 当连接池耗尽时是否等待
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", that.Host+":"+ObjToStr(that.Port),
redis.DialConnectTimeout(5*time.Second),
redis.DialReadTimeout(3*time.Second),
redis.DialWriteTimeout(3*time.Second),
)
if err != nil {
return nil, err
}
if that.Pwd != "" {
if _, err := conn.Do("AUTH", that.Pwd); err != nil {
conn.Close()
return nil, err
}
}
return conn, nil
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
if time.Since(t) < time.Minute {
return nil
}
_, err := c.Do("PING")
return err
},
}
}
return true
})
}
// getConn 从连接池获取连接
func (that *CacheRedis) getConn() redis.Conn {
that.initPool()
if that.pool == nil {
return nil
}
return that.pool.Get()
}
func (that *CacheRedis) del(key string) {
conn := that.getConn()
if conn == nil {
return
}
defer conn.Close()
del := strings.Index(key, "*")
if del != -1 {
val, err := redis.Strings(that.conn.Do("KEYS", key))
if err != nil {
return
}
that.conn.Send("MULTI")
for i, _ := range val {
that.conn.Send("DEL", val[i])
}
that.conn.Do("EXEC")
} else {
_, err := that.conn.Do("DEL", key)
val, err := redis.Strings(conn.Do("KEYS", key))
if err != nil {
that.Error.SetError(err)
return
}
if len(val) == 0 {
return
}
conn.Send("MULTI")
for i := range val {
conn.Send("DEL", val[i])
}
_, err = conn.Do("EXEC")
if err != nil {
that.Error.SetError(err)
}
} else {
_, err := conn.Do("DEL", key)
if err != nil {
that.Error.SetError(err)
_, err = that.conn.Do("PING")
if err != nil {
if that.reCon() {
_, err = that.conn.Do("DEL", key)
}
}
}
}
}
// key value ,时间为时间戳
func (that *CacheRedis) set(key string, value string, time int64) {
_, err := that.conn.Do("SET", key, value, "EX", ObjToStr(time))
if err != nil {
func (that *CacheRedis) set(key string, value string, expireSeconds int64) {
conn := that.getConn()
if conn == nil {
return
}
defer conn.Close()
_, err := conn.Do("SET", key, value, "EX", ObjToStr(expireSeconds))
if err != nil {
that.Error.SetError(err)
_, err = that.conn.Do("PING")
if err != nil {
if that.reCon() {
_, err = that.conn.Do("SET", key, value, "EX", ObjToStr(time))
}
}
}
}
func (that *CacheRedis) get(key string) *Obj {
reData := &Obj{}
conn := that.getConn()
if conn == nil {
return reData
}
defer conn.Close()
var err error
reData.Data, err = redis.String(that.conn.Do("GET", key))
reData.Data, err = redis.String(conn.Do("GET", key))
if err != nil {
reData.Data = nil
if !strings.Contains(err.Error(), "nil returned") {
that.Error.SetError(err)
_, err = that.conn.Do("PING")
if err != nil {
if that.reCon() {
reData.Data, err = redis.String(that.conn.Do("GET", key))
}
}
return reData
}
}
return reData
@@ -123,19 +154,13 @@ func (that *CacheRedis) get(key string) *Obj {
func (that *CacheRedis) Cache(key string, data ...interface{}) *Obj {
reData := &Obj{}
if that.conn == nil {
re := that.reCon()
if !re {
return reData
}
}
//查询缓存
if len(data) == 0 {
reData = that.get(key)
return reData
}
tim := int64(0)
//删除缓存
if len(data) == 1 && data[0] == nil {
@@ -144,21 +169,17 @@ func (that *CacheRedis) Cache(key string, data ...interface{}) *Obj {
}
//添加缓存
if len(data) == 1 {
if that.TimeOut == 0 {
//that.Time = Config.GetInt64("cacheShortTime")
}
tim += that.TimeOut
}
if len(data) == 2 {
that.Error.SetError(nil)
tempt := ObjToInt64(data[1], that.Error)
if tempt > tim {
tim = tempt
} else if that.GetError() == nil {
tim = tim + tempt
}
}
@@ -166,5 +187,4 @@ func (that *CacheRedis) Cache(key string, data ...interface{}) *Obj {
that.set(key, ObjToStr(data[0]), tim)
return reData
}