1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import (
    "database/sql"
    "errors"
    "log"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

var ConnPoll chan *Conn
var maxIdleConns = 10 // 最大空闲
var maxIdleTime = 10  // 最大空闲时间,10s
var maxOpenConns = 20 // 最大连接数

const (
    host = "xxxxxx"
    user = "xxxxxx"
    pass = "xxxxxx"
    db   = "xxxxxx"
)

type Conn struct {<!-- -->
    conn    *sql.DB
    lastUse time.Time
}

func addConn(conn *Conn) {<!-- -->
    if ConnPoll == nil {<!-- -->
        ConnPoll = make(chan *Conn, maxOpenConns)
    }
    if len(ConnPoll) >= maxOpenConns {<!-- -->
        conn.conn.Close()
        return
    }
    ConnPoll <- conn
}

func initDB() {<!-- -->
    if len(ConnPoll) == 0 {<!-- -->
        ConnPoll = make(chan *Conn, maxOpenConns)
        for i := 0; i < maxOpenConns/2; i++ {<!-- -->
            db, err := sql.Open("mysql", user+":"+pass+"@tcp("+host+":3306)/"+db+"?charset=utf8")
            if err != nil {<!-- -->
                log.Println(err)
            }
            addConn(&Conn{<!-- -->conn: db})
        }
    }
}

func GetConn() (conn *Conn, err error) {<!-- -->
    if ConnPoll == nil || len(ConnPoll) == 0 {<!-- -->
        initDB()
    }

    // 获取连接,超时控制
    select {<!-- -->
    case <-time.After(time.Second * time.Duration(3)):
        err = errors.New("timeout")
    case conn = <-ConnPoll:

    }

    return conn, nil
}

主要使用channel来实现。