mysql - golang MySQL "connection refused"

标签 mysql go connection-refused

我是 Go (Golang) 的新手。我写了一个简单的基准程序来测试 MySQL 的并发处理。当我增加并发 channel 数时,不断收到“dial tcp 52.55.254.165:3306: getsockopt: connection refused”、“unexpected EOF”错误。

每个 go 例程都将 1 到 n 行批量插入到一个简单的客户表中。该程序允许设置可变插入大小(单个语句中的行数)和并行 go 例程的数量(每个 go 例程执行上面的一个插入)。程序在小数字 row<100 和 number go routines<100 时运行良好。但是当数量增加时,尤其是并行 go 例程的数量增加时,开始出现意外的 EOF 错误。

寻找线索。基于它们,我设置了数据库最大连接数以及“max_allowed_pa​​cket”和“max_connections”。我还设置了 go 程序 db.db.SetMaxOpenConns(200), db.SetConnMaxLifetime(200), db.SetMaxIdleConns(10)。我已经尝试过大数字和小数字(从 10 到 2000)。似乎没有什么可以解决该程序。

我打开了一个全局数据库连接。下面的代码片段:

// main package

func main() {

    var err error
    db, err = sql.Open("mysql","usr:pwd@tcp(ip:3306)/gopoc")
    if err != nil {
        log.Panic(err)
    }
    db.SetMaxOpenConns(1000)
    db.SetConnMaxLifetime(1000)
    db.SetMaxIdleConns(10)

    // sql.DB should be long lived "defer" closes it once this function ends
    defer db.Close()

    if err = db.Ping(); err != nil {
        log.Panic(err)
    }

    http.HandleFunc("/addCust/", HFHandleFunc(addCustHandler))

    http.ListenAndServe(":8080", nil)
}

// add customer handler
func addCustHandler(w http.ResponseWriter, r *http.Request) {

    // experected url: /addCust/?num=3$pcnt=1
    num, _ := strconv.Atoi(r.URL.Query().Get("num"))
    pcnt, _ := strconv.Atoi(r.URL.Query().Get("pcnt"))

    ch := make([]chan string, pcnt) // initialize channel slice
    for i := range ch {
        ch[i] = make(chan string, 1)
    }

    var wg sync.WaitGroup

    for i, chans := range ch {
        wg.Add(1)
        go func(cha chan string, ii int) {
            defer wg.Done()
            addCust(num)
            cha <- "Channel[" + strconv.Itoa(ii) + "]\n"
        }(chans, i)
    }

    wg.Wait()

    var outputstring string

    for i := 0; i < pcnt; i++ {
        outputstring = outputstring + <-ch[i]
    }

    fmt.Fprintf(w, "Output:\n%s", outputstring)
}

func addCust(cnt int) sql.Result {
...
    sqlStr := "INSERT INTO CUST (idCUST, idFI, fName, state, country) VALUES "

    for i := 0; i < cnt; i++ {

        sqlStr += "(" + strconv.Itoa(FiIDpadding+r.Intn(CidMax)+1) + ", " + strconv.Itoa(FiID) +", 'fname', 'PA', 'USA), " 

    }

    //trim the last ,
    sqlStr = sqlStr[0:len(sqlStr)-2] + " on duplicate key update lname='dup';"

    res, err := db.Exec(sqlStr)
    if err != nil {
        panic("\nInsert Statement error\n" + err.Error()) 
    }

    return res
}

最佳答案

我想你在每个例程中都调用了 sql.Open?

Open 函数应该只调用一次。您应该在例程之间共享打开的数据库连接。 Open函数返回的DB可以并发使用,有自己的pool

关于mysql - golang MySQL "connection refused",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42501182/

相关文章:

go - 了解接口(interface)中的接口(interface)(嵌入式接口(interface))

apache - Laravel 服务在本地主机上收到 ERR_CONNECTION_REFUSED

c++ - 在 C++ 项目中使用 mysql_query 进行多个查询

php - 用户/管理员通过 PHP 登录

go - Go Playground 和我机器上的 Go 之间存在差异?

linux - 如何在 RHEL 6.4 上打开特定端口?

Hadoop 2.6 多节点集群在运行示例 jar 时因连接异常而失败

php - mySQL 语句未在 PHP 变量声明中运行

mysql - 根据MySQL中不同表中某些列的值匹配两列

去绝对进口和Travis CI