[Go] golang實現mysql鏈接池

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函數

相關文章
相關標籤/搜索