初めに

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以下の値を設定で、ずっと再利用可能。

以下のようにして実装。

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
}
广告
将在 10 秒后关闭
bannerAds