首页 > 解决方案 > golang mysql连接不好

问题描述

$ wrk -c300 -d10m -t8 url
SetMaxOpenConns(100)

wrk刚启动的时候,偶尔出现bad connection error,而且mysql PROCESSLIST的个数不到100,70左右我修改了文件

数据库/sql/sql.go

func OpenDB(c driver.Connector) *DB {
    ctx, cancel := context.WithCancel(context.Background())
    db := &DB{
        connector:    c,
        openerCh:     make(chan struct{}, connectionRequestQueueSize),
        resetterCh:   make(chan *driverConn, 50),
        lastPut:      make(map[*driverConn]string),
        connRequests: make(map[uint64]chan connRequest),
        stop:         cancel,
    }

    go db.connectionOpener(ctx)
    go db.connectionResetter(ctx)

    return db
}

更改了 resetterCh 的缓冲区长度

resetterCh:   make(chan *driverConn, 100),

解决了bad connection问题,mysql PROCESSLIST数量瞬间达到100

我的解决方案有问题吗?

最小可重现示例

package main

import (
    "fmt"
    "github.com/jinzhu/gorm"
    "net/http"

    _ "github.com/go-sql-driver/mysql"
    //_ "github.com/jinzhu/gorm/dialects/mysql"
    "time"
)

var (
    MysqlClient *gorm.DB
)

const (
    user = ""
    pwd = ""
    host = ""
    port = ""
    dbname = ""
)

func main() {
    initMysqlDb()

    http.HandleFunc("/", ActionHandler)
    http.ListenAndServe(":18001", nil)

}

type Reguserinfo struct {
    Rid              int       `gorm:"primary_key;column:rid;type:int(10) unsigned;not null" json:"rid"`
    Username         string    `gorm:"unique;column:username;type:varchar(64);not null" json:"username"`
}

func initMysqlDb() {
    var err error

    uri := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local&interpolateParams=true",
        user, pwd, host, port, dbname)
    MysqlClient, err = gorm.Open("mysql", uri)
    if err != nil {
        fmt.Println("mysql open err", err)
        return
    }

    // SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
    MysqlClient.DB().SetMaxIdleConns(10)

    // SetMaxOpenConns sets the maximum number of open connections to the database.
    MysqlClient.DB().SetMaxOpenConns(100)

    // SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
    MysqlClient.DB().SetConnMaxLifetime(100 * time.Second)
    MysqlClient.LogMode(false)

    MysqlClient.SingularTable(true) //表名后默认+s,关闭之
}

func ActionHandler(w http.ResponseWriter, r *http.Request)  {
    var result *gorm.DB
    var registerInfo Reguserinfo

    result = MysqlClient.Where("rid = ?", 2).First(&registerInfo)
    if result.Error != nil {
        fmt.Println("err", result.Error)
    }
    w.Write([]byte("hello"))
}

shell run wrk -c300 -d10m -t8 http://127.0.0.1:18001/

这个例子可以重现

标签: mysqlgo

解决方案


推荐阅读