zylthinking 发表于 2017-06-07 17:46

golang 如何连 mysql 不要每次建立一个连接

本帖最后由 zylthinking 于 2017-06-07 17:48 编辑

@cokeboL, 有没有趟过这个坑?
mysql 自己认最大链接 150,
现在是设置了
       db.SetMaxOpenConns(10);
      db.SetMaxIdleConns(10);

不起作用;
stmt.Close() 也调用了
row.Close() 也调用了

就是不起作用;
一次调用创建一个新连接, 150次准挂

我就不明白了, 这还有救吗



func db_get() (*sql.DB, error) {
    if (db != nil) {
      return db, nil;
    }

    mux.Lock();
    if (db != nil) {
      mux.Unlock();
      return db, nil;
    }

    conf := setting.Conf;
    if (conf == nil) {
      mux.Unlock();
      return nil, errors.New("can't get mysql configuration");
    }

    var buf bytes.Buffer;
    buf.WriteString(conf.Mysql.User);
    buf.WriteByte(':');
    buf.WriteString(conf.Mysql.Passwd);
    buf.WriteString("@tcp(");
    buf.WriteString(conf.Mysql.Addr);
    buf.WriteString(")/db?charset=utf8");
    db, err := sql.Open("mysql", buf.String());
    if (err == nil) {
       db.SetMaxOpenConns(10);
      db.SetMaxIdleConns(10);
    }
    mux.Unlock();
    return db, err;
}

func UserGet(email string) (*Account, error) {
    db, err := db_get();
    if (err != nil) {
      return nil, err;
    }

    stmt, err := db.Prepare("select * from account where email = ?");
    if (err != nil) {
      return nil, err;
    }
    defer stmt.Close();

    row, err:= stmt.Query(email);
    if (err != nil) {
      return nil, err;
    }
    defer row.Close();

    obj, err := fill_row(row, &Account{});
    if (err != nil) {
      return nil, err;
    } else if (obj == nil) {
      return nil, nil;
    }
    return obj.(*Account), nil;
}


zylthinking 发表于 2017-06-07 18:44

靠, 我知道怎么会是了

db, err := sql.Open("mysql", buf.String());
这个声明了一个新的本地变量 db, 而不是全局 db 变量;导致全局 db 永远是 nil, 从而不断创建 db 对象导致的, 坑的你没话说

cokeboL 发表于 2017-06-07 22:21

解决了就好,但是为啥每次一个新连接?弄个连接池哇

cokeboL 发表于 2017-06-07 22:23

额,没看一楼代码,刚细看到二楼解释

我用的 mymysql,这个据说比官方的要好点:mrgreen:

yulihua49 发表于 2017-06-12 12:12

本帖最后由 yulihua49 于 2017-06-12 12:20 编辑

zylthinking 发表于 2017-06-07 17:46
@cokeboL, 有没有趟过这个坑?
mysql 自己认最大链接 150,
现在是设置了

不管哪种语言,不管哪种数据库,每次一个连接都不是好办法。
应该有一个中间件,负责管理有限的数据库连接。成千上万的客户端通过中间件来使用数据库。
这个中间件的服务器,管理着N个数据库连接池,每个池有M个连接。每个客户端可以选择请求某个池。每个池都有一个队列。配置适当参数可以使数据库在最大负载能力下工作。客户端排队能够保证总体的最低平均响应时间。

150个连接,一般可供应上万客户端的使用。

zylthinking 发表于 2017-06-12 18:30

回复 5# yulihua49

你都没搞清楚是怎么回事, 就开始飙常识................

yulihua49 发表于 2017-06-13 15:48

本帖最后由 yulihua49 于 2017-06-13 15:57 编辑

zylthinking 发表于 2017-06-12 18:30
回复 5# yulihua49

你都没搞清楚是怎么回事, 就开始飙常识................
我回帖时你的问题已经解决。就对每次一个连接提议。而且,你看看你的题目,我的回答不扣题吗?你居然。。。。。。。不说了。
一哥们,做erlang接口,用C访问数据库,每次请求插入一个记录,居然:打开-插入-commit-关闭。每条记录干这么一圈。我也是这么建议的。

shang2010 发表于 2017-06-20 15:20

以前游戏公司,代码很淳朴,c/cpp的,一个服务器就一个连接,


golang不熟,没玩过:em03:

windoze 发表于 2017-06-26 14:23

你开几个goroutine专门处理MySQL,有数据库请求通过channel发过来给这几个goroutine处理,这样就不会爆了。

cokeboL 发表于 2017-06-26 16:38

回复 9# windoze

如果数据库操作之后还有代码,用channel 就要回调了,不好:curse:
页: [1] 2
查看完整版本: golang 如何连 mysql 不要每次建立一个连接