go 关于使用gorm 连接数超出最大限制的问题以及解决方案

  • 首先查看连接服务器的数据库的最大连接数配置
    mysql -uroot -p
    #输入mysql root 用户密码
    show variables like \'%max_connections%\';
    #查看mysql 最大连接数  (我3.10 机器默认配置是151 这里我把它改成256)
    set GLOBAL max_connections=256;
    #再查看是否修改成功
    show variables like \'%max_connections%\';
  • go代码实现
    package appservice
    
    import (
        "gormdemo/models"
        "sync"
        "time"
    
        "gorm.io/driver/mysql"
        "gorm.io/gorm"
    )
    
    const stopTimeout = time.Second * 10
    
    const dsn = "root:123456@tcp(192.168.3.10:3306)/go_testdb?charset=utf8mb4&parseTime=True&loc=Local"
    
    var (
        once sync.Once
        db   *gorm.DB
    )
    
    func openDbConnection() *gorm.DB {
        db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
        sqlDB, err := db.DB()
        sqlDB.SetMaxIdleConns(10) //空闲连接数
        sqlDB.SetMaxOpenConns(100)//最大连接数
        sqlDB.SetConnMaxLifetime(time.Minute)
        if err != nil {
            panic("连接数据库失败!")
        }
        return db
    }
    
    func init() {
        db = openDbConnection()
        // migration
        db.AutoMigrate(&models.User{})
    }
    
    // 创建用户
    func Create(user *models.User) {
        if user == nil {
            panic("用户不存在!")
        } else {
            result := db.Create(user)
            if result.Error != nil && result.RowsAffected == 0 {
                panic("添加失败:" + result.Error.Error())
            }
        }
    }
    
    // 更新用户
    func Update(user *models.User) bool {
        if user == nil {
            panic("用户不存在!")
        } else {
            // 查最新的用户
            var existUser models.User
            result := db.Where("email = ?", *user.Email).First(&existUser)
            if result.RowsAffected > 0 {
                existUser.Name = user.Name
                existUser.Age = user.Age
                existUser.Email = user.Email
                existUser.Birthday = user.Birthday
                db.Save(&existUser)
            } else {
                panic("用户不存在!")
            }
    
        }
        return true
    }
    
    // 获取用户
    func Get(id uint) *models.User {
        var user models.User
        db.First(&user, id)
        return &user
    }
    
    // 删除用户
    func Delete(id uint) bool {
        db.Delete(&models.User{}, id)
        return true
    }
    
    // 获取所有用户
    func GetUserAll() *[]models.User {
        var users []models.User
        result := db.Select([]string{}).Find(&users)
        if result.RowsAffected > 0 {
            return &users
        }
        return nil
    }
  • 核心代码在openDbConnection方法内的最大连接数设置。 这里默认值是0 (也就是不做任何限制), 如果不根据服务端的最大连接数设置的话,并发起来的时候可能会报Too many connections
  • 还有根据测算这里的最大连接数并不是设置的越大越好的。根据服务器的配置进行相应的设置才能使得吞吐量最大化。