Mysql: 使用多个并发 goroutine 时出现“拨号 tcp 127.0.0.1:3306:连接:无法分配请求的地址”

创建于 2019-01-17  ·  3评论  ·  资料来源: go-sql-driver/mysql

问题描述

一段时间后,当使用多个并发 goroutines 时,我收到“拨号 tcp 127.0.0.1:3306:连接:无法分配请求的地址”:

  • 当使用 8 个并发 goroutines => 一切正常
  • 当使用更多 goroutines => 大约 15 秒后,每个请求都会失败并显示 err="dial tcp 127.0.0.1:3306: connect: cannot assign requestsed address"。 在第一次失败之前,已经成功执行了大约 35 000 个请求。

看起来 sql 驱动程序无法获得新端口来建立新连接,但如果是这样,我不明白为什么它不重用池中的现有连接?

发生错误时,我有以下 DBStats:
(sql.DBStats) {
MaxOpenConnections: (int) 0,
OpenConnections: (int) 64,
使用中:(int) 64,
空闲:(整数)0,
等待计数:(int64)0,
WaitDuration: (time.Duration) 0s,
MaxIdleClosed: (int64) 28252,
MaxLifetimeClosed: (int64) 0
}

我使用 go-sql-driver V1.4.1 和 go 1.11.2,以访问作为 docker 容器在本地运行的 mariaDB。
在下面的示例中,我添加了“恐慌”只是为了不被一堆类似的错误淹没。

示例代码

// the below code is called repetitly from a configurable number of worker fed using channels (fan-out)
// Mark visa_card entry as migrated
        query := fmt.Sprintf(UPDATE visa_card SET migrated=TRUE WHERE id_card=%s, this.idCard)
        _, err = conf.MySql.ExecContext(ctx, query)
        if err != nil {
            log.Error(ctx, log.EventTypeBusiness, "", err)
            spew.Dump(conf.MySql.Stats())
            panic("the END")
        }
        return err

错误日志

{"level":"info","dateTime":"2019-01-17T14:58:04.095+0100","msg":"","appVersion":"0.0.0","component":"VISA-MIGRATOR","country":"bw","eventType":"incoming request","requestId":"d25e58f8-8228-4a7f-9cc4-1fd9ea2230b4","useCase":"","parameters":{"request_headers":{},"request_http_method":"POST","request_uri":"/startImportActiveCards"},"caller":"common/utils/log/ginLog.go:70"}
{"level":"error","dateTime":"2019-01-17T14:58:20.562+0100","msg":"","appVersion":"0.0.0","component":"VISA-MIGRATOR","country":"bw","eventType":"internal","requestId":"d25e58f8-8228-4a7f-9cc4-1fd9ea2230b4","useCase":"startMigration","peer":"internal","caller":"migrator/migrate/migrateActiveCards.go:211","errorDetails":"dial tcp 127.0.0.1:3306: connect: cannot assign requested address"}
(sql.DBStats) {
 MaxOpenConnections: (int) 0,
 OpenConnections: (int) 50,
 InUse: (int) 50,
 Idle: (int) 0,
 WaitCount: (int64) 0,
 WaitDuration: (time.Duration) 0s,
 MaxIdleClosed: (int64) 28258,
 MaxLifetimeClosed: (int64) 0
}
panic: the END

配置

*go-sql-driver V1.4.1

*Go 版本:go 版本 go1.11.2 linux/amd64

*MariaDB 10.4.1 在 docker 容器中

服务器操作系统:例如 Debian 8.1 (Jessie)、Windows 10

最有用的评论

试试这个。

db.SetMaxIdleConns(64)
db.SetMaxOpenConns(64)
db.SetConnMaxLifetime(time.Minure)

所有3条评论

试试这个。

db.SetMaxIdleConns(64)
db.SetMaxOpenConns(64)
db.SetConnMaxLifetime(time.Minure)

非常感谢@methane的快速回复,试用成功!
我仍然对默认值无法正常工作感到有些惊讶,我不明白为什么,但您确实解决了我的问题。

看到这篇文章。
http://techblog.en.klab-blogs.com/archives/31093990.html

文章中的所有图像都消失了。 他们在文章的日文版中还活着。

http://dsas.blog.klab.org/archives/2018-02/configure-sql-db.html

此页面是否有帮助?
0 / 5 - 0 等级