LoginSignup
3
2

More than 3 years have passed since last update.

DBコネクションプールをgolangで実現

Last updated at Posted at 2020-10-22

初めに

GCPをつかっていてコネクションプールの話に行き着きました。
「最大コネクション数が100を超えました」というエラーが発生。
なぜコネクション数が多くなってしまうのかを調べ、見つけた対処方法となります。

環境

クラウド:GCP
WEBサーバーをVue/CloudRun
APIサーバーをGolang/CloudRun
DBサーバーをMySQL/CloudSQL

原因

APIを叩くたびにAPIサーバーとDBサーバー間で新しいコネクションができているから

と判明した。

つまり、コネクションの使い回しができていなかった。

対策

database.sqlの以下のメソッドを使用し、コネクションプールの設定を行う。
また、ORMでもコネクションプールできるらしい。

メソッド名 説明
func (db *DB) SetMaxOpenConns(n int) 接続の最大数を設定。 nに0以下の値を設定で、接続数無制限。
func (db *DB) SetMaxIdleConns(n int) コネクションプールの最大接続数を設定。
func (db *DB) SetConnMaxLifetime(d time.Duration) 接続の再利用が可能な時間を設定。dに0以下の値を設定で、ずっと再利用可能。

以下のようにして実装。

DBconnection
func NewLocalDBConnection() error {
    /* ===== connect datebase ===== */
    // user
    user := os.Getenv("MYSQL_USER") 
    // password
    password := os.Getenv("MYSQL_PASSWORD") 
    // connection database
    database := os.Getenv("MYSQL_DATABASE") 
    // connection host
    host := "localhost" 
    // connection port
    port := "3306" 

    var err error
    DB, err = setupDB("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", user, password, host, port, database))
    if err != nil {
        return fmt.Errorf("sql.Open: %v", err)
    }

    return err
}

//this function is a function for connection pooling
func setupDB(Driver string, dsn string) (*sql.DB, error) {
    db, err := sql.Open(Driver, dsn)
    if err != nil {
        return nil, err
    }
    //コネクションプールの最大接続数を設定。
    db.SetMaxIdleConns(100)
    //接続の最大数を設定。 nに0以下の値を設定で、接続数は無制限。
    db.SetMaxOpenConns(100)
    //接続の再利用が可能な時間を設定。dに0以下の値を設定で、ずっと再利用可能。
    db.SetConnMaxLifetime(100 * time.Second)

    return db, err
}
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2