增加mysql redis的docker版
This commit is contained in:
parent
8de9252ae5
commit
3ee707e60c
|
|
@ -0,0 +1,105 @@
|
|||
package mysql
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"gorm.io/plugin/dbresolver"
|
||||
)
|
||||
|
||||
/*
|
||||
docker配置
|
||||
|
||||
MYSQL_DSN=root:root@tcp(mysql:3306)/sample?charset=utf8mb4&parseTime=True&loc=Local \
|
||||
MYSQL_MAXLIFETIME=2\
|
||||
MYSQL_MAXIDLECONNS=2\
|
||||
MYSQL_MAXOPENCONNS=200\
|
||||
MYSQL_INIT=true \
|
||||
*/
|
||||
var (
|
||||
_db *gorm.DB
|
||||
)
|
||||
|
||||
// 创建实例
|
||||
func newDB() (*gorm.DB, error) {
|
||||
if _db != nil {
|
||||
return _db, nil
|
||||
}
|
||||
|
||||
dsn := os.Getenv("MYSQL_DSN")
|
||||
if dsn == "" {
|
||||
dsn = "root:root@tcp(127.0.0.1:3306)/mysql?charset=utf8&parseTime=True&loc=Local"
|
||||
}
|
||||
maxLifetime := func() int {
|
||||
c := os.Getenv("MYSQL_MAXLIFETIME")
|
||||
cc, err := strconv.Atoi(c)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if cc <= 0 {
|
||||
return 1
|
||||
}
|
||||
if cc >= 1000 {
|
||||
cc = 1000
|
||||
}
|
||||
return cc
|
||||
}()
|
||||
maxIdleConns := func() int {
|
||||
c := os.Getenv("MYSQL_MAXIDLECONNS")
|
||||
cc, err := strconv.Atoi(c)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if cc < 0 {
|
||||
return 0
|
||||
}
|
||||
if cc >= 1000 {
|
||||
cc = 1000
|
||||
}
|
||||
return cc
|
||||
}()
|
||||
maxOpenConns := func() int {
|
||||
c := os.Getenv("MYSQL_MAXOPENCONNS")
|
||||
cc, err := strconv.Atoi(c)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if cc < 0 {
|
||||
return 0
|
||||
}
|
||||
if cc >= 1000 {
|
||||
cc = 1000
|
||||
}
|
||||
return cc
|
||||
}()
|
||||
|
||||
var err error
|
||||
_db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||
SkipDefaultTransaction: true,
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
SingularTable: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_db.Use(
|
||||
dbresolver.Register(dbresolver.Config{
|
||||
Sources: []gorm.Dialector{mysql.Open(dsn)},
|
||||
Replicas: []gorm.Dialector{mysql.Open(dsn)},
|
||||
Policy: dbresolver.RandomPolicy{},
|
||||
}).SetConnMaxIdleTime(time.Hour).
|
||||
SetConnMaxLifetime(time.Duration(maxLifetime) * time.Hour).
|
||||
SetMaxIdleConns(maxIdleConns).
|
||||
SetMaxOpenConns(maxOpenConns))
|
||||
return _db, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package mysql
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"myschools.me/suguo/intelligent-community/model"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//不初始化表时返回
|
||||
if os.Getenv("MYSQL_INIT") != "true" {
|
||||
return
|
||||
}
|
||||
|
||||
db, err := newDB()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.User{}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
redigo "github.com/gomodule/redigo/redis"
|
||||
)
|
||||
|
||||
/*
|
||||
REDIS_DSN=127.0.0.1:6379 \
|
||||
REDIS_PWD=eYX7EwxKPCDmwMtyKVge8oLd2t81 \
|
||||
REDIS_DB=0 \
|
||||
*/
|
||||
var pool *redigo.Pool
|
||||
|
||||
func init() {
|
||||
dbNumber := func() int {
|
||||
db := os.Getenv("REDIS_DB")
|
||||
database, err := strconv.Atoi(db)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
if database < 0 {
|
||||
database = 0
|
||||
}
|
||||
if database > 16 {
|
||||
database = 0
|
||||
}
|
||||
return database
|
||||
}()
|
||||
pool = &redigo.Pool{
|
||||
MaxActive: 100,
|
||||
MaxIdle: 1,
|
||||
IdleTimeout: time.Second * time.Duration(60),
|
||||
Dial: func() (redigo.Conn, error) {
|
||||
return redigo.Dial("tcp", os.Getenv("REDIS_DSN"),
|
||||
redigo.DialDatabase(dbNumber),
|
||||
redigo.DialPassword(os.Getenv("REDIS_PWD")),
|
||||
)
|
||||
},
|
||||
TestOnBorrow: func(conn redigo.Conn, t time.Time) error {
|
||||
if time.Since(t) < time.Minute {
|
||||
return nil
|
||||
}
|
||||
_, err := conn.Do("PING")
|
||||
return err
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetBytes 获取一个字节数组值
|
||||
func GetBytes(key *string) (*[]byte, error) {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
data, err := redigo.Bytes(conn.Do("GET", *key))
|
||||
return &data, err
|
||||
}
|
||||
|
||||
// Get 获取一个值
|
||||
func Get(key string) interface{} {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
if data, err = redigo.Bytes(conn.Do("GET", key)); err != nil {
|
||||
return nil
|
||||
}
|
||||
var reply interface{}
|
||||
if err = json.Unmarshal(data, &reply); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return reply
|
||||
}
|
||||
|
||||
// 集合Set增加元素
|
||||
func SetAdd(key string, data ...interface{}) error {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
var err error
|
||||
for _, d := range data {
|
||||
_, e := conn.Do("SADD", key, d)
|
||||
if e != nil {
|
||||
err = e
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 集合Set删除元素
|
||||
func SetRem(key string, data ...interface{}) error {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
var err error
|
||||
for _, d := range data {
|
||||
_, e := conn.Do("SREM", key, d)
|
||||
if e != nil {
|
||||
err = e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// 集合Set判断是否存在成员member,结果.(int64)==1表示存在
|
||||
func SetIsMember(key string, member interface{}) (interface{}, error) {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
return conn.Do("SISMEMBER", key, member)
|
||||
}
|
||||
|
||||
// 设置一个值
|
||||
func Set(key string, val interface{}, timeout time.Duration) error {
|
||||
data, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return SetBytes(&key, &data, timeout)
|
||||
}
|
||||
|
||||
func SetBytes(key *string, data *[]byte, timeout time.Duration) error {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
_, err := conn.Do("SETEX", *key, int64(timeout/time.Second), *data)
|
||||
return err
|
||||
}
|
||||
|
||||
// IsExist 判断key是否存在
|
||||
func IsExist(key string) bool {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
a, _ := conn.Do("EXISTS", key)
|
||||
i := a.(int64)
|
||||
return i > 0
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func Delete(key string) error {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
if _, err := conn.Do("DEL", key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Expire 失效时间配置
|
||||
func Expire(key string, t int64) error {
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
if _, err := conn.Do("expire", key, t); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"myschools.me/suguo/intelligent-community/model"
|
||||
)
|
||||
|
||||
// 存储用户的Token
|
||||
func UserTokenSet(key *string, usr *model.User) error {
|
||||
|
||||
err := Set(*key, usr, 7210*time.Second)
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "UserTokenSet",
|
||||
}).Warnf("Set: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 从redis中获取用户信息,最佳实践经验建议把此代码放service层
|
||||
func UserTokenGet(token *string) (*model.User, error) {
|
||||
b, err := GetBytes(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if b == nil {
|
||||
return nil, errors.New("无效token,请重新登录!")
|
||||
}
|
||||
|
||||
var user *model.User
|
||||
if err := json.Unmarshal(*b, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
Loading…
Reference in New Issue