配置文件
package conf
import (
"flag"
"gopkg.in/yaml.v2"
"io/ioutil"
"IRIS_WEB/utility/db"
)
var Conf *Config
var _path string
func init() {
flag.StringVar(&_path, "c", "./config.yaml", "default config path")
}
func InitConfig() error {
Conf = &Config{}
content, err := ioutil.ReadFile(_path)
if err == nil {
err = yaml.Unmarshal(content, Conf)
}
return err
}
type Config struct {
Server ServerConf `yaml:"server"`
Mysql db.MysqlConf `yaml:"mysql"`
Redis db.RedisConf `yaml:"redis"`
}
type ServerConf struct {
Port int `yaml:"port"`
}
mysql初始化
package db
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
var mysqlDB *gorm.DB
type MysqlConf struct {
Dsn string `yaml:"dsn"`
MaxIdle int `yaml:"maxIdle"`
MaxOpen int `yaml:"maxOpen"`
}
func InitMysql(conf *MysqlConf) (err error){
mysqlDB, err = gorm.Open("mysql", conf.Dsn)
if err == nil {
mysqlDB.DB().SetMaxIdleConns(conf.MaxIdle)
mysqlDB.DB().SetMaxOpenConns(conf.MaxOpen)
mysqlDB.DB().SetConnMaxLifetime(time.Duration(30) * time.Minute)
err = mysqlDB.DB().Ping()
}
return
}
func GetMysql() *gorm.DB {
return mysqlDB
}
func CloseMysql() {
if mysqlDB != nil {
mysqlDB.Close()
}
}
Redis初始化
package db
import (
"errors"
"github.com/garyburd/redigo/redis"
"time"
)
var redisPool *redis.Pool
type RedisConf struct {
Addr string `yaml:"addr"`
DB int `yaml:"db"`
MaxIdle int `yaml:"maxIdle"`
MaxOpen int `yaml:"maxOpen"`
}
func InitRedis(conf *RedisConf) (err error) {
redisPool = &redis.Pool{
MaxIdle: conf.MaxIdle,
MaxActive: conf.MaxOpen,
IdleTimeout: time.Duration(30) * time.Minute,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", conf.Addr, redis.DialDatabase(conf.DB))
},
}
conn := GetRedis()
defer conn.Close()
if r, _ := redis.String(conn.Do("PING")); r != "PONG" {
err = errors.New("redis connect failed.")
}
return
}
func GetRedis() redis.Conn {
return redisPool.Get()
}
func CloseRedis() {
if redisPool != nil {
redisPool.Close()
}
}
使用redis做异步锁
package locker
import (
"IRIS_WEB/utility/db"
"errors"
"github.com/garyburd/redigo/redis"
"time"
)
type Locker struct {
Key string
Error error
}
func Lock(key string) (locker *Locker) {
locker = &Locker{Key: key}
conn := db.GetRedis()
defer conn.Close()
r, _ := redis.String(conn.Do("SET", key, 1, "EX", 60, "NX"))
if r != "OK" {
locker.Error = errors.New("locker failed.")
}
return
}
func TryLock(key string, timeout time.Duration) (locker *Locker) {
locker = &Locker{Key: key}
conn := db.GetRedis()
defer conn.Close()
start := time.Now()
for time.Now().Sub(start) < timeout {
reply, _ := redis.String(conn.Do("SET", key, 1, "EX", 60, "NX"))
if reply == "OK" {
return
}
time.Sleep(time.Duration(200) * time.Millisecond)
}
locker.Error = errors.New("locker timeout.")
return
}
func (lock *Locker) Close() {
if lock.Error == nil {
conn := db.GetRedis()
defer conn.Close()
conn.Do("DEL", lock.Key)
}
}
使用redis做缓存
package cache
import (
"IRIS_WEB/utility/db"
"errors"
"github.com/garyburd/redigo/redis"
"time"
)
func Set(key, val string, ttl time.Duration) error {
conn := db.GetRedis()
defer conn.Close()
r, err := redis.String(conn.Do("SET", key, val, "EX", ttl.Seconds()))
if err != nil {
return err
}
if r != "OK" {
return errors.New("NOT OK")
}
return nil
}
func Get(key string) (string, error) {
conn := db.GetRedis()
defer conn.Close()
r, err := redis.String(conn.Do("GET", key))
if err != nil {
return "", err
}
return r, nil
}