1. 程式人生 > >golang go-sql-drive mysql連線池的實現 golang go-sql-drive mysql連線池的實現

golang go-sql-drive mysql連線池的實現 golang go-sql-drive mysql連線池的實現

golang go-sql-drive mysql連線池的實現


golang內部自帶了連線池功能,剛開始接觸golang的時候不瞭解這個,還自己搞了一個 sql.Open的物件管理池,真的非常囧啊。

sql.Open函式實際上是返回一個連線池物件,不是單個連線。在open的時候並沒有去連線資料庫,只有在執行query、exce方法的時候才會去實際連線資料庫。在一個應用中同樣的庫連線只需要儲存一個sql.Open之後的db物件就可以了,不需要多次open。

因為普通程式執行完畢之後資源就會被釋放掉,所以這裡嘗試使用web服務進行演示。

開啟web服務

首頁先啟動一個web服務監聽9090埠,比較簡單不多做說明。

1 2 3 4 5 6 7 func startHttpServer() {      http.HandleFunc( "/pool" , pool)      err := http.ListenAndServe( ":9090"
, nil)      if err != nil {          log.Fatal( "ListenAndServe: " , err)      } }

db物件初始化

宣告一個全域性的db物件,並進行初始化。

1 2 3 4 5 6 7 8 var db *sql.DB   func init() {      db, _ = sql.Open( "mysql" "root:@tcp(127.0.0.1:3306)/test?charset=utf8" )      db.SetMaxOpenConns( 2000 )      db.SetMaxIdleConns( 1000 )      db.Ping() }

連線池的實現關鍵在於SetMaxOpenConns和SetMaxIdleConns,其中:

SetMaxOpenConns用於設定最大開啟的連線數,預設值為0表示不限制。
SetMaxIdleConns用於設定閒置的連線數。

設定最大的連線數,可以避免併發太高導致連線mysql出現too many connections的錯誤。設定閒置的連線數則當開啟的一個連線使用完成後可以放在池裡等候下一次使用。

請求方法

上面開啟http請求設定了請求/pool地址的執行方法

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 func pool(w http.ResponseWriter, r *http.Request) {      rows, err := db.Query( "SELECT * FROM user limit 1" )      defer rows.Close()      checkErr(err)        columns, _ := rows.Columns()      scanArgs := make([] interface {}, len(columns))      values := make([] interface {}, len(columns))      for j :=  range values {          scanArgs[j] = &values[j]      }        record := make( map [string]string)      for rows.Next() {          //將行資料儲存到record字典          err = rows.Scan(scanArgs...)          for i, col :=  range values {              if col != nil {                  record[columns[i]] = string(col.([]byte))              }