使用Redigo操作(4)使用连接池

首先

在本文中,我们将看到如何使用Redigo这个针对Go语言的Redis客户端库。我们将重点关注连接池的使用方法。

环境

    • OS: Windows 10

 

    • Redis: win-3.2.100

Go言語: 1.11

基本的步骤

连接池是一种功能,通过重用连接来加速与Redis服务器的连接。

首先,我們來看一個使用Redigo的連接池的典型程式碼。

package main

import (
    "fmt"
    "time"

    "github.com/gomodule/redigo/redis"
)

func newPool(addr string) *redis.Pool {
    return &redis.Pool{
        MaxIdle:     3,
        MaxActive:   0,
        IdleTimeout: 240 * time.Second,
        Dial:        func() (redis.Conn, error) { return redis.Dial("tcp", addr) },
    }
}

func main() {
    // コネクションプールの作成
    pool := newPool("localhost:6379")

    // コネクションの取得
    conn := pool.Get()
    defer conn.Close()

    // 値の書き込み
    w, err := conn.Do("SET", "temperature", 20)
    if err != nil {
        panic(err)
    }
    fmt.Println(w) // OK

    // 値の取得
    r, err := redis.Int(conn.Do("GET", "temperature"))
    if err != nil {
        panic(err)
    }
    fmt.Println(r) // 20
}

首先要创建redis.Pool结构体,在需要进行Redis操作的时候,使用pool.Get()从连接池获取连接,完成后再使用conn.Close()关闭连接,这是基本的使用方法。

在使用Web应用程序的服务器时,我认为可以在启动时创建一个连接池并将其保留在全局变量等中,在处理请求的函数开头使用`pool.Get()`和`defer conn.Close()`的写法。

泳池连接管理

让我们来理解游泳池连接管理和参数设置的方法。

在池启动之初,池处于没有任何连接的状态。当调用pool.Get时,池会建立一条新的连接与服务器之间,并将其作为返回值返回。当调用conn.Close关闭该连接时,池不会断开与服务器之间的连接,而是将其保留为”空闲状态”的连接。然后,当再次调用pool.Get时,池会将空闲状态的连接更改为”占用状态”并作为返回值返回。如果没有空闲状态的连接,则会建立新的连接。

默认情况下,只要资源允许,可以建立任意数量的连接。使用参数MaxActive可以设置连接的上限。当超过MaxActive数量并尝试使用pool.Get获取连接进行conn.Do操作时,将返回ErrPoolExhausted错误。或者,将Wait参数设置为true,可以使pool.Get的调用被阻塞,直到连接数低于MaxActive为止。

同时,通过MaxIdle参数,可以设置连接空闲状态的上限。当连接的conn.Close方法被调用时,如果已经存在达到上限数量的空闲连接,连接池将不会将连接置于空闲状态,并且会断开与服务器的连接。

以下是理解上述行为的代码。在最大空闲连接数MaxIdle = 3和最大活动连接数MaxActive = 6的情况下,尝试建立和关闭10个连接,并通过pool.Stats输出所得到的连接池状态。

package main

import (
    "fmt"
    "time"

    "github.com/gomodule/redigo/redis"
)

func newPool(addr string) *redis.Pool {
    return &redis.Pool{
        MaxIdle:     3,
        MaxActive:   6,
        IdleTimeout: 240 * time.Second,
        Dial:        func() (redis.Conn, error) { return redis.Dial("tcp", addr) },
    }
}

func printStats(pool *redis.Pool) {
    s := pool.Stats()
    fmt.Printf("Active: %d, Idle: %d, InUse: %d\n",
        s.ActiveCount, s.IdleCount, s.ActiveCount-s.IdleCount)
}

func main() {
    // コネクションプールの作成
    pool := newPool("localhost:6379")

    printStats(pool)
    fmt.Println("------")

    // コネクションを作成
    conns := make([]redis.Conn, 10, 10)
    for i := 0; i < 10; i++ {
        conns[i] = pool.Get()
        printStats(pool)
    }
    fmt.Println("------")

    // コネクションをクローズ
    for i := 0; i < 10; i++ {
        conns[i].Close()
        printStats(pool)
    }
}

请确认实际结果如下:活动(即使用中加上闲置)的连接数量不超过6个,并且闲置数量不会超过3个。

Active: 0, Idle: 0, InUse: 0
------
Active: 1, Idle: 0, InUse: 1
Active: 2, Idle: 0, InUse: 2
Active: 3, Idle: 0, InUse: 3
Active: 4, Idle: 0, InUse: 4
Active: 5, Idle: 0, InUse: 5
Active: 6, Idle: 0, InUse: 6
Active: 6, Idle: 0, InUse: 6
Active: 6, Idle: 0, InUse: 6
Active: 6, Idle: 0, InUse: 6
Active: 6, Idle: 0, InUse: 6
------
Active: 6, Idle: 1, InUse: 5
Active: 6, Idle: 2, InUse: 4
Active: 6, Idle: 3, InUse: 3
Active: 5, Idle: 3, InUse: 2
Active: 4, Idle: 3, InUse: 1
Active: 3, Idle: 3, InUse: 0
Active: 3, Idle: 3, InUse: 0
Active: 3, Idle: 3, InUse: 0
Active: 3, Idle: 3, InUse: 0
Active: 3, Idle: 3, InUse: 0

默认情况下,空闲状态的连接不会永远关闭。可以通过设置IdleTimeout或MaxConnLifetime参数来设置关闭的期限。一旦连接进入空闲状态并经过了IdleTimeout的时间,连接将被关闭。同时,一旦连接建立并经过了MaxConnLifetime的时间,连接也将被关闭。

最后

我看了一下Redigo的连接池使用方法。

请引用以下内容:

    • Redigoを使う(1) 基本的な使い方

 

    • Redigoを使う(2) 様々なデータ型を扱う

 

    • Redigoを使う(3) トランザクションを行う

 

    • Redigoを使う(5) ユーティリティ関数

 

    Redigoを使う(6) パブリッシュ/サブスクライブ
广告
将在 10 秒后关闭
bannerAds