连接池有两个作用:
1.创建数据库连接是一个很耗时的操作
2.控制连接数
Beego orm连接池分析
1.orm结构中的alias
type orm struct {
alias *alias
db dbQuerier
isTx bool
}
type alias struct {
Name string
Driver DriverType
DriverName string
DataSource string
MaxIdleConns int
MaxOpenConns int
DB *sql.DB
DbBaser dbBaser
TZ *time.Location
Engine string
}
再看sql.DB结构
type DB struct {
// Atomic access only. At top of struct to prevent mis-alignment
// on 32-bit platforms. Of type time.Duration.
waitDuration int64 // Total time waited for new connections.
connector driver.Connector
// numClosed is an atomic counter which represents a total number of
// closed connections. Stmt.openStmt checks it before cleaning closed
// connections in Stmt.css.
numClosed uint64
mu sync.Mutex // protects following fields
freeConn []*driverConn
然后看orm的RegisterDataBase方法
db, err = sql.Open(driverName, dataSource)
if err != nil {
err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error())
goto end
}
al, err = addAliasWthDB(aliasName, driverName, db)
if err != nil {
goto end
}
...
for i, v := range params {
switch i {
case 0:
SetMaxIdleConns(al.Name, v)
case 1:
SetMaxOpenConns(al.Name, v)
}
}
然后再到SetMaxIdleConns方法里面看
func SetMaxIdleConns(aliasName string, maxIdleConns int) {
al := getDbAlias(aliasName)
al.MaxIdleConns = maxIdleConns
al.DB.SetMaxIdleConns(maxIdleConns)
}
其实最终还是调用了go的database/sql 里的方法 al.DB.SetMaxIdleConns,其中al是一个sql实例
即调用了sql.DB.SetMaxIdleConns方法
大家都知道,go的sql本来就是用的连接池。
那么我们继续看看go的sql包连接池是怎样实现的。
我们先看sql.DB这个结构体
type DB struct {
// Atomic access only. At top of struct to prevent mis-alignment
// on 32-bit platforms. Of type time.Duration.
waitDuration int64 // Total time waited for new connections.
connector driver.Connector
// numClosed is an atomic counter which represents a total number of
// closed connections. Stmt.openStmt checks it before cleaning closed
// connections in Stmt.css.
numClosed uint64
mu sync.Mutex // protects following fields
freeConn []*driverConn
注意“freeConn []*driverConn”,这个就是存放连接的池子。
db.conn这个方法里面,技术和重新分配db.freeConn
numFree := len(db.freeConn)
那么db.conn这个方法在哪里调用呢?
db.prepare,db.exec,db.query等查询的时候。
到此,我们可以一窥Go在sql连接处理上的大概了。
网友评论