Thanks to visit codestin.com
Credit goes to github.com

Skip to content

全部连接被关闭后导致hang(阻塞) #32

@upwell

Description

@upwell

现象:

当有较多的goroutine在等待从Pool中Get连接,同时没有空闲连接时,有种情况,当被使用的连接,同时出错并被调用者Close掉时,等待获取连接的goroutine会一直阻塞等待从connReq这个channel获取连接,而所有的连接都已经被关闭了,不会再有可用的连接,导致一直等待,程序hang住。

原因

Get方法中,第133行检查完已创建的连接数达到了最大值后,会等待从connReq的channel等待其它goroutine Put回来的连接。
Close方法中,会把openingConns--,但已经没法触发Get方法去新建连接了,Get方法都被阻塞在从connReq的channel拿连接了。

Get方法133行

pool/channel.go

Line 133 in 58e025e

if c.openingConns >= c.maxActive {

pool/channel.go

Lines 130 to 140 in 58e025e

default:
c.mu.Lock()
log.Debugf("openConn %v %v", c.openingConns, c.maxActive)
if c.openingConns >= c.maxActive {
req := make(chan connReq, 1)
c.connReqs = append(c.connReqs, req)
c.mu.Unlock()
ret, ok := <-req
if !ok {
return nil, ErrMaxActiveConnReached
}

Close方法

pool/channel.go

Lines 202 to 213 in 58e025e

func (c *channelPool) Close(conn interface{}) error {
if conn == nil {
return errors.New("connection is nil. rejecting")
}
c.mu.Lock()
defer c.mu.Unlock()
if c.close == nil {
return nil
}
c.openingConns--
return c.close(conn)
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions