微服务成倍增加postgres连接

时间:2018-12-27 04:54:14

标签: postgresql go

我有一个通过golang编写的服务,它作为使用者使用,它从kafka的队列中获取数据并将其存储在PostgreSQL数据库中。在执行某些请求时,golang开始增加PG连接数,然后超过它们的限制。我不知道为什么,请帮助我解决这个问题。 这是代码:

func SaveMessageStatus(msg models.Message) error {

db := GetPostgreInstance() // Get *sql.DB instance

// Проверяем есть ли записи

rows, err := db.Query(`select * from "tNotifStatus" where "NotificationId" = $1`, msg.NotificationID)

if err != nil {
    CheckError(err, "SLCT status", "")
    return err
}

if rows.Next() {
    // Смотрим если запись в таблице уже есть, тогда просто обновляем статусы по сообщению
    fsql := `update "tNotifStatus" set "Status" = $1, "Error" = $2, "UpdateTime" = $3 where "NotificationId" = $4`

    _, err = db.Exec(fsql, msg.Status, msg.Error, msg.UpdateTime, msg.NotificationID)

    if err != nil {
        //Логируем
        CheckError(err, "UPDT status", "")
        return err
    }

} else {
    // Если записей нет, то создаем новую
    fsql := `insert into "tNotifStatus" values ($1,$2,$3,$4,$5)`
    _, err = db.Exec(fsql, msg.NotificationID, msg.Status, msg.Error, msg.ChannelName, msg.UpdateTime)
    if err != nil {
        //Логируем
        CheckError(err, "INS status", "")
        return err
    }
}
return err

}

如果看到PG管理员监控,我们有很多新连接:

6460 UCS ucs 10.3.40.20 2018-12-27 09:35:14 +06空闲客户端:ClientRead
46462 UCS ucs 10.3.40.20 2018-12-27 09:35:17 +06空闲客户端:ClientRead
46463 UCS ucs 10.3.40.20 2018-12-27 09:35:17 +06空闲客户端:ClientRead
46517 UCS ucs 10.3.40.20 2018-12-27 09:36:20 +06空闲客户端:ClientRead
46518 UCS ucs 10.3.40.20 2018-12-27 09:36:21 +06空闲客户端:ClientRead
46520 UCS ucs 10.3.40.20 2018-12-27 09:36:22 +06空闲客户端:ClientRead
46521 UCS ucs 10.3.40.20 2018-12-27 09:36:23 +06空闲客户端:ClientRead
46522 UCS ucs 10.3.40.20 2018-12-27 09:36:23 +06空闲客户端:ClientRead
46524 UCS ucs 10.3.40.20 2018-12-27 09:36:24 +06空闲客户端:ClientRead
46525 UCS ucs 10.3.40.20 2018-12-27 09:36:24 +06空闲客户端:ClientRead
46527 UCS ucs 10.3.40.20 2018-12-27 09:36:25 +06空闲客户端:ClientRead
46529 UCS ucs 10.3.40.20 2018-12-27 09:36:25 +06空闲客户端:ClientRead
46531 UCS ucs 10.3.40.20 2018-12-27 09:36:26 +06空闲客户端:ClientRead
46532 UCS ucs 10.3.40.20 2018-12-27 09:36:26 +06空闲客户端:ClientRead
46534 UCS ucs 10.3.40.20 2018-12-27 09:36:27 +06空闲客户端:ClientRead

他们都尝试执行

select * from "tNotifStatus" where "NotificationId" = $1

可能与Wait Event(ClientRead)有关,golang lib启动了新连接,而旧连接仍在尝试完成“ SELECT”

以下是与数据库的连接代码

    func GetPostgreInstance() *sql.DB {
    return postgreClient
}

func InitPqConnection() {

    var err error

    var configuration models.Configuration
    configuration.Load()

    connStr := configuration.PostgreConnString

    postgreClient, err = sql.Open("postgres", connStr)
    if err != nil {
        CheckError(err, "Connection to db", "")
        panic("Error connection to DB")
    }
    fmt.Println("Connected to db")
}

1 个答案:

答案 0 :(得分:3)

您需要使用QueryRow(),因为您既不会使用也不希望有多行记录,所以您需要使用defer rows.Close()(使用{{ 1}}

https://golang.org/pkg/database/sql/#Rows.Close

  

Close关闭行,防止进一步枚举。如果调用Next并返回false,并且没有其他结果集,则将自动关闭行,这将足以检查Err的结果。关闭是幂等的,不会影响Err的结果。

http://go-database-sql.org/retrieving.html

  

如果出于某种原因退出循环(提前返回等),则行不会关闭,连接保持打开状态。

.Query

由于您甚至没有遍历rows, err := db.Query(`select * from "tNotifStatus" where "NotificationId" = $1`, msg.NotificationID) if err != nil { CheckError(err, "SLCT status", "") return err } defer rows.Close() ,因此您基本上不会达到自动关闭条件,并且始终保持连接打开。