使用Redigo这个库
package main import ( "fmt" "redis" "time" "strconv" ) var ( server string = "192.168.1.105:6379" password string = "passwd" ) var pool *redis.Pool func test(i int) { c := pool.Get() defer c.Close() t:=strconv.Itoa(i) c.Do("SETEX","foo"+t,20,i) reply, err := redis.Int(c.Do("GET","foo"+t)) if err == nil { fmt.Print(reply) } else { fmt.Print(err) } time.Sleep(1*time.Second) } func poolInit() (*redis.Pool) { //redis pool return &redis.Pool{ MaxIdle: 3, IdleTimeout: 240 * time.Second, Dial: func () (redis.Conn, error) { c, err := redis.Dial("tcp", server) if err != nil { return nil, err } if _, err := c.Do("AUTH", password); err != nil { c.Close() return nil, err } //if _, err := c.Do("SELECT",1); err != nil { // c.Close() // return nil, err //} return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err }, } } func main() { pool = poolInit() for i:=0;i<1000000;i++ { test(i) } }
如果服务器端口不可用或者服务i不可用,则c.Do会返回错误,端口不可用立即返回Connection Refused,而服务器不可达会等待一段时间超时再返回。下面这段代码实现先查找缓存,查询失败时查询mysql
type Record struct { Key string Val string } func fetch_key(key string) string { var val string out := make(chan string) timeout := make(chan string, 1) //超时两秒 go func() { time.Sleep(2 * time.Second) timeout <- "" }() //查询缓存(Redis) c := G_pool.Get() defer c.Close() if reply, err := redis.String(c.Do("GET", key)); err == nil { go func(string) { out <- reply }(reply) } else { go func() { //查询数据库(Mysql) db, e := sql.Open("mysql", "username:password@tcp(mysqlip:mysqlport)/dbname?charset=utf8") if e != nil { out <- "" } defer db.Close() rows, e := db.Query("select key,val from dbname.tablename where key=" + key) if e != nil { out <- "" } if rows == nil { out <- "" } for rows.Next() { rec := new(Record) row_err := rows.Scan(&rec.Key,&rec.Val) if row_err != nil { out <- "" } //将结果存入缓存(Redis),超时1天 c.Do("SETEX",key,86400,rec.Val) out <- rec.Size } out <- "" }() } //等待结果或者超时 select { case val = <-timeout: case val = <-out: } return val }
有疑问加站长微信联系(非本文作者)