golang中鏈接mysql數據庫,須要使用一個第三方類庫github.com/go-sql-driver/mysql,在這個類庫中就實現了mysql的鏈接池,而且只須要設置兩個參數就能夠實現mysql
通常鏈接mysql首先須要調用sql.Open函數,可是此時並無真正的去鏈接mysql,而是隻建立了一個Db的對象而已。當執行Query或者是Exec方法時,纔會去真正的鏈接數據庫。git
默認狀況下。每次執行sql語句,都會建立一條tcp鏈接,執行結束就會斷掉鏈接,可是會保留兩條鏈接閒置。當下次再執行 sql時,先用閒置的鏈接,不夠的時候再去建立鏈接。github
當設置了Db類下的這兩個參數,就能夠真正的實現鏈接池了。
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(5)golang
SetMaxOpenConns(10)是設置的最大鏈接數,也就是甭管你多少併發,只能最多建立10條tcp鏈接,還有要注意的一點是,當執行完sql,鏈接轉移到rows對象上,若是rows不關閉,這條鏈接不會被放回池裏,其餘併發獲取不到鏈接會被阻塞住。
SetMaxIdleConns(5)是設置的執行完閒置的鏈接,這些就算是執行結束了sql語句仍是會保留着的sql
測試的流程是這樣的,首先在代碼中併發100次執行sql,開一個窗口不停的netstat查看3306端口看tcp鏈接的狀況,能夠看到最大就10條tcp鏈接,執行完後會有5條鏈接保持住,開一個窗口看tcpdump中3306端口的數據請求狀況,在閒置鏈接的時候,會每10秒傳遞數據給mysql,使得閒置鏈接保持住。數據庫
mysqlClient.go
先要拉取一下github包,go get github.com/go-sql-driver/mysql併發
package main import ( "database/sql" "fmt" "time" _ "github.com/go-sql-driver/mysql" ) func main() { db, _ := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gocron") db.SetMaxOpenConns(10) db.SetMaxIdleConns(5) //鏈接數據庫查詢 for i := 0; i < 100; i++ { go func(i int) { mSql := "select * from user" rows, _ := db.Query(mSql) rows.Close() //這裏若是不釋放鏈接到池裏,執行5次後其餘併發就會阻塞 fmt.Println("第 ", i) }(i) } for { time.Sleep(time.Second) } }
開一個窗口不停的netstat
while true;do clear;date;netstat -altupn|grep 3306|grep Client;sleep 1;donetcp
開一個窗口tcpdump看閒置鏈接的請求狀況,每隔15秒請求一次數據
tcpdump -i lo port 3306 -vv函數