You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang Goroutine操作MySQL遇连接超限问题求助

问题分析与修复方案

代码核心问题

  • 每个goroutine创建独立连接池:getData函数中每次执行sql.Open都会新建一个数据库连接池,每个池还设置了8个最大连接。5000个goroutine同时启动会瞬间创建海量连接,直接触发MySQL的连接数上限。
  • 连接池配置完全无效:局部db实例的连接池参数(SetMaxOpenConns/SetMaxIdleConns)无法全局生效,起不到限流作用。
  • 资源管理混乱:每个goroutine结束时调用db.Close()关闭整个连接池,导致连接频繁创建销毁,引发connection reset by peer错误。

修复后的代码

type Page struct {
    Stat int
}

func main() {
    cfg := mysql.Config{
        // 你的数据库配置
    }
    // 初始化全局共享连接池
    db, err := sql.Open("mysql", cfg.FormatDSN())
    checkError(err)
    // 根据MySQL的max_connections配置合理调整,示例设为30
    db.SetMaxOpenConns(30)
    db.SetMaxIdleConns(10)
    db.SetConnMaxLifetime(time.Minute * 3)
    defer db.Close() // 程序退出时关闭全局连接池

    // 5000个group id
    groups := []int{}

    // 信号量控制并发数,和连接池最大打开数匹配
    sem := make(chan struct{}, 30)
    pages := make(chan Page, len(groups))

    for _, id := range groups {
        sem <- struct{}{}
        go func(id int) {
            defer func() { <-sem }()
            count, err := getData(id, db)
            checkError(err)
            pages <- Page{Stat: count}
        }(id)
    }

    // 收集所有结果
    for range groups {
        page := <-pages
        fmt.Println(page.Stat)
    }
}

func getData(i int, db *sql.DB) (int, error) {
    rows, err := db.Query(`select g.id from goods as g where g.groupid = ?`, i)
    if err != nil {
        return 0, err
    }
    defer rows.Close()

    count := 0
    var id1 int // 修复原代码未声明变量的问题
    for rows.Next() {
        err = rows.Scan(&id1)
        if err != nil {
            return 0, err
        }
        count++
    }
    // 检查结果集遍历后的潜在错误
    if err = rows.Err(); err != nil {
        return 0, err
    }
    return count, nil
}

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

关键修复说明

  • 全局复用连接池:在main中仅初始化一次*sql.DB,所有goroutine共享该连接池,连接池参数才能真正控制整体连接数量。
  • 并发限流:通过信号量限制goroutine并发数,避免连接池过载,并发数建议和SetMaxOpenConns值保持一致。
  • 补全变量声明与错误处理:修复原代码中id1未声明的编译错误,增加rows.Err()检查避免遗漏结果集遍历错误。

内容的提问来源于stack exchange,提问作者Алексей Морозов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:25:20