Giter VIP home page Giter VIP logo

Comments (7)

caibirdme avatar caibirdme commented on July 24, 2024

实际上Open只是返回了一个*sql.DB对象,而设置SetConnMaxLifetime每个项目都有自己的诉求,可以自己设置。这里Open(true)时ping一下只是简单帮忙确认一下连接是否可用。

from gendry.

caibirdme avatar caibirdme commented on July 24, 2024

manager的职责是帮你拼接用于和mysql server进行握手的dataSourceName,本来需要手动设置的字面量这里改为了方法调用,仅此而已。对*sql.DB本身的行为设置还是交给用户

from gendry.

zplzpl avatar zplzpl commented on July 24, 2024

“Open(true)时ping一下只是简单帮忙确认一下连接是否可用”

Ping的时候,如果没有可用的connection,它是会创建的。那么这时候这条连接,在没设置max life time就是永久存在。

当进行执行query有可能会用到这条connection,而它已经被mysql server close掉之后,那么会抛出 invalid connection

from gendry.

caibirdme avatar caibirdme commented on July 24, 2024

首先,根据官方文档

Open may just validate its arguments without creating a connection to the database. 
To verify that the data source name is valid, call Ping.

Open只是创建了一个内存中的结构体,只有Ping方法才会去检测你的连接设置是否正确(当然这意味着会新建一个连接)。这种检测是有必要的,因为数据库如果根本连不上的话,业务逻辑就完全没法处理,应该及早panic或者做其它处理。详见这个issue

其次,如果你新设置了MaxLifetime为d,d秒过后之前的连接就可能被清理掉。由于连接池也只会定期清掉一些空闲的过期的连接,换句话说,即使你设置了MaxLifetime,也不能保证所有连接都在有效期内,源码

		expiredSince := nowFunc().Add(-d)
		var closing []*driverConn
		for i := 0; i < len(db.freeConn); i++ {
			c := db.freeConn[i]
			if c.createdAt.Before(expiredSince) {
				closing = append(closing, c)
				last := len(db.freeConn) - 1
				db.freeConn[i] = db.freeConn[last]
				db.freeConn[last] = nil
				db.freeConn = db.freeConn[:last]
				i--
			}
		}
		db.maxLifetimeClosed += int64(len(closing))
		db.mu.Unlock()

		for _, c := range closing {
			c.Close()
		}

在高负载的情况下,使用完的连接通常不会放入freeConn队列中,而是直接交给下一个请求使用了。所以很可能你使用的连接早就过了maxLifetime了。

而连接本身被对端关闭或者信道出问题这种情况在任何时候都会出现,不会因为你设置了什么参数就可以避免的,如果有可能你需要自己去处理这些error

from gendry.

zplzpl avatar zplzpl commented on July 24, 2024

"连接本身被对端关闭或者信道出问题这种情况在任何时候都会出现"

那么遇到这种情况,你的处理方式会是?类似重试记录日志这样的操作?

其实我认为只要max life time 设置小于wait timeout 足够多(让其有机会放到freeConn),这里我也不好量化,但应该能避免很多问题。再报invalid connection,直接打印日志,就可以了。

from gendry.

zplzpl avatar zplzpl commented on July 24, 2024

被端关闭,原因有很多,但我发现实际场景更多是因为配置导致比如 wait timeout

from gendry.

caibirdme avatar caibirdme commented on July 24, 2024

怎么设置MaxLifetime,怎么处理不可避免的连接错误,这就是用户方需要考虑的问题了,向上抛错误或者重试都是可能的,这不是gendry需要关注的。

一开始创建的那个连接在你设置完MaxLifetime之后下个周期就会被回收,它在这个期间出现问题的概率和你先设置完MaxLifetime再建立连接然后这个连接在下个回收周期到来之前出现问题的概率是几乎一样的。

不过如果你纠结的是Open(true)帮你Ping了一下的话,你完全可以Open(false)

from gendry.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.