golang redisの使用(二)
redis接続プール接続プールは,以前に確立した接続を多重化することを目的とし,毎回TCP接続を再構築することなくスループットを向上させる.MaxIdle:poolで最大Idle接続数MaxActive:poolで最大に割り当てられた接続数をいくつかのパラメータで説明します.IdleTimeout:idleの時間を0に設定し、idleの時間を超えて接続を閉じます.0 idleに設定した接続はcloseWaitではありません:trueに設定し、要求時にMaxActiveに達すると接続がcloseされるのを待つことになります.falseに設定すると、要求時にMaxActiveに達するとerrorが返されます.
テスト時に検出
Close()は常に実行されていないので、MaxActiveに達すると引っかかり、実行されません.使用済みで直接c.Close()を呼び出す原因はよく調べていませんが、誰か原因がわかったら教えてください
詳細コード:https://github.com/BinWang-sh...
package main
import (
"fmt"
"os"
"sync"
"time"
redis "github.com/gomodule/redigo/redis"
)
const (
MAXIDLE = 50
MAXACTIVE = 5000
IDLETIMEOUT = 30 * time.Second
ROUNTINECOUNT = 50
)
func deferClose(con *redis.Conn) {
fmt.Println("close")
(*con).Close()
}
func main() {
redisPool := &redis.Pool{
MaxIdle: MAXIDLE,
MaxActive: MAXACTIVE,
IdleTimeout: IDLETIMEOUT,
Wait: true,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp",
"172.17.84.205:6379",
redis.DialKeepAlive(20*time.Second),
redis.DialPassword("123456"),
redis.DialConnectTimeout(15*time.Second),
redis.DialReadTimeout(15*time.Second),
redis.DialWriteTimeout(15*time.Second))
if err != nil {
fmt.Println(err)
}
return c, err
},
}
var wg sync.WaitGroup
wg.Add(2 * ROUNTINECOUNT)
for i := 0; i < ROUNTINECOUNT; i++ {
go func(routineNum int) {
for cnt := 0; cnt < 1000; cnt++ {
c := redisPool.Get()
//defer c.Close()
key := fmt.Sprintf("key_%d_%d", routineNum, cnt)
value := fmt.Sprintf("value_%d_%d", routineNum, cnt)
_, err := c.Do("set", key, value)
if err != nil {
fmt.Printf("set %s:%v
", key, err)
}
fmt.Printf("s %s
", value)
if cnt%50 == 0 {
aCount := redisPool.Stats().ActiveCount
wCount := redisPool.Stats().WaitCount
fmt.Printf("activeCount:%d, waitCount:%d
", aCount, wCount)
}
c.Close()
//time.Sleep(50 * time.Millisecond)
}
wg.Done()
}(i)
go func(routineNum int) {
for cnt := 0; cnt < 1000; cnt++ {
c := redisPool.Get()
//defer c.Close()
key := fmt.Sprintf("key_%d_%d", routineNum, cnt)
value, err := redis.String(c.Do("get", key))
if err != nil {
fmt.Printf("get %s:%v
", key, err)
}
fmt.Printf("g %s
", value)
c.Close()
}
wg.Done()
}(i)
}
wg.Wait()
}
func errCheck(err error) {
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
テスト時に検出
c := redisPool.Get()
defer c.Close()
Close()は常に実行されていないので、MaxActiveに達すると引っかかり、実行されません.使用済みで直接c.Close()を呼び出す原因はよく調べていませんが、誰か原因がわかったら教えてください
詳細コード:https://github.com/BinWang-sh...