1. simple example
package main
import (
"context"
"fmt"
"log"
"github.com/go-redis/redis/v8"
)
func main() {
// 创建Redis客户端
client := redis.NewClient(&redis.Options{
Addr: "dbconn.sealosbja.site:43360", // Redis服务器地址
Username: "",
Password: "", // 密码,如果没有密码则为空字符串
DB: 0, // 使用的数据库编号
})
ctx := context.Background()
// Ping测试连接
pong, err := client.Ping(ctx).Result()
if err != nil {
log.Fatal("Could not connect to Redis: ", err)
}
fmt.Println(pong, err)
// 设置键值对
err = client.Set(ctx, "key", "value", 0).Err()
if err != nil {
fmt.Println(err)
}
// 获取键值对
val, err := client.Get(ctx, "key").Result()
if err != nil {
fmt.Println(err)
}
fmt.Println("key:", val)
}
2. redis pool
package main
import (
"fmt"
"time"
redigo "github.com/gomodule/redigo/redis"
)
func main() {
var addr = "dbconn.sealosbja.site:43360"
var username = "default"
var password = "7jkmb4jk"
pool := PoolInitRedis(addr, username, password)
// 返回值为activeConn类型,有三个属性,第一个属性为连接池指针对象,第二个属性为连接指针对象,第二个为state表示连接状态
/**
* type activeConn struct {
* p *Pool
* pc *poolConn
* state int
*}
**/
c1 := pool.Get()
c2 := pool.Get()
c3 := pool.Get()
c4 := pool.Get()
// 超过MacActive,Wait参数为false,获取的连接失败;true会阻塞等待
c5 := pool.Get()
// &{0xc00012c500 0xc00015c460 0} &{0xc00012c500 0xc0002220a0 0} &{0xc00012c500 0xc0000be320 0} &{0xc00012c500 0xc00015c780 0} {0x801900}
fmt.Println(c1, c2, c3, c4, c5)
fmt.Println(pool.ActiveCount()) // 4
c1.Close()
c2.Close()
c3.Close() // 超过MaxIdle的连接,在被释放的时候会被自动关闭
c4.Close()
c5.Close()
// &{0xc00012c500 <nil> 0} &{0xc00012c500 <nil> 0} &{0xc00012c500 <nil> 0} &{0xc00012c500 <nil> 0} {0x801900}
fmt.Println(c1, c2, c3, c4, c5)
fmt.Println(pool.ActiveCount()) // 2
// 未超过idleTimeou,可以复用两个连接,再新建两个连接
time.Sleep(time.Second * 3)
c1 = pool.Get()
c2 = pool.Get()
c3 = pool.Get()
c4 = pool.Get()
c5 = pool.Get()
// &{0xc00012c500 0xc00015c780 0} &{0xc00012c500 0xc0000be320 0} &{0xc00012c500 0xc000222370 0} &{0xc00012c500 0xc0002225a0 0} {0x801900}
// 0xc00015c780 0xc0000be320为复用连接,其余2个为新建连接
fmt.Println(c1, c2, c3, c4, c5)
fmt.Println(pool.ActiveCount()) // 4
c1.Close()
c2.Close()
c3.Close() // 超过MaxIdle的连接,在被释放的时候会被自动关闭
c4.Close()
c5.Close()
// 超过idleTimeou,两个idle的连接中Get的时候被释放;这里的所有四个连接都是新的tcp连接
time.Sleep(10 * time.Second)
c1 = pool.Get()
c2 = pool.Get()
c3 = pool.Get()
c4 = pool.Get()
c5 = pool.Get()
// &{0xc00012c500 0xc000222690 0} &{0xc00012c500 0xc0000be820 0} &{0xc00012c500 0xc0000bea50 0} &{0xc00012c500 0xc0000bebe0 0} {0x801900}
fmt.Println(c1, c2, c3, c4, c5)
fmt.Println(pool.ActiveCount()) // 4
c1.Close()
c2.Close()
c3.Close() // 超过MaxIdle的连接,在被释放的时候会被自动关闭
c4.Close()
c5.Close()
time.Sleep(time.Second * 10)
b1 := pool.Get()
b2 := pool.Get()
b3 := pool.Get()
// 超过idleTimeout,所有连接都新建,redis一共有3个连接
// &{0xc00012c500 0xc00015ceb0 0} &{0xc00012c500 0xc000222a50 0} &{0xc00012c500 0xc00015d1d0 0}
fmt.Println(b1, b2, b3)
fmt.Println(pool.IdleCount()) // 0
fmt.Println(pool.ActiveCount()) // 3
time.Sleep(time.Second * 5)
pool.Close()
}
// redis pool
func PoolInitRedis(server, username, password string) *redigo.Pool {
return &redigo.Pool{
// 最大空闲连接数;没有redis操作时依然可以保持这个连接数量,但要在IdleTimeout的时间范围内,不然就会关闭.
// 但是连接只会在从pool中重新get的时候判断并释放,如果不从连接中get是不会释放的
MaxIdle: 2,
IdleTimeout: 5 * time.Second, // 最大空闲时间
MaxActive: 4, //最大数
//Wait: true, // 连接池满时,Get()会等待而不是返回错误
Dial: func() (redigo.Conn, error) {
c, err := redigo.Dial("tcp", server)
if err != nil {
return nil, err
}
if username != "" && password != "" {
if _, err := c.Do("AUTH", username, password); err != nil {
c.Close()
return nil, err
}
}
return c, err
},
TestOnBorrow: func(c redigo.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
}
评论