doushuo1080 2015-07-07 03:14
浏览 145
已采纳

如果不使用,数据库将挂起

I have a web application I am starting. Works fine upon startup but if I leave it (for say, an hour) and hit it with another request the query hangs. I thought about closing it after each query then opening up a new connection but the docs explicitly say "It is rare to Close a DB, as the DB handle is meant to be long-lived and shared between many goroutines.". What am I doing wrong?

package main

import (
  "database/sql"
  "log"
  "net/http"
  _ "github.com/lib/pq"
)

var Db *sql.DB

func main() {
  var err error
  Db, err = sql.Open("postgres", "user=me password=openupitsme host=my.host.not.yours dbname=mydb sslmode=require")
  if err != nil {
    log.Fatal("Cannot connect to db: ", err)
  }
  http.HandleFunc("/page", myHandler)
  http.ListenAndServe(":8080", nil)
}

func myHandler(w http.ResponseWriter, r *http.Request) {
  log.Println("Handling Request....", r)
  query := `SELECT pk FROM mytable LIMIT 1`
  rows, err := Db.Query(query)
  if err != nil {
    log.Println(err)
  }
  defer rows.Close()
  for rows.Next() {
    var pk int64
    if err := rows.Scan(&pk); err != nil {
      log.Println(err)
    }
    log.Println(pk)
  }
  log.Println("Request Served...")
}

EDIT #1: My postgres log shows:

2015-07-08 18:10:01 EDT [7710-1] user@here LOG:  could not receive data from client: Connection reset by peer
2015-07-08 18:20:01 EDT [7756-1] user@here LOG:  could not receive data from client: Connection reset by peer
  • 写回答

1条回答 默认 最新

  • douhuiqi3855 2015-07-13 04:35
    关注

    I have experienced similar issues. In our case, the problem was caused by a connection tracking firewall located between the client machine and the database.

    Such firewalls keep track of TCP level connections, and in order to limit resource usage, then will time out connections which to them appear inactive for an extended period. The symptoms we observed in this case were very similar to yours: at the client end, the connection appears to be hanging, while at the server end you can see connection reset by peer.

    One way to prevent this is to ensure that TCP Keepalives are enabled, and that the keepalive interval is less than the timeout of the firewalls, routers, etc which are causing your connection issue. This is controlled by the libpq connection parameters keepalives, keepalives_idle, keepalives_interval and keepalives_count which you can set in the connection string. See the manual for a description of these parameters.

    • keepalive determines if the keepalive function is enabled or not. It defaults to 1 (enabled) so you probably do not need to specify this.
    • keepalives_idle determines the amount of idle time before it will send a keepalive. If you do not specify this, it will default to the default for the operating system.

      In a Linux system you can see the default by examining /proc/sys/net/ipv4/tcp_keepalive_time - in my server it is set to 7200 seconds, which would be too long in your case, since your observation is that the connection is dropped after ~1 hour.

      You could try setting it to, say, 2500 seconds.

    The Linux Documentation Project provides a useful TCP Keepalive HOWTO document that describes how they work in some detail.

    Note that not all operating systems support TCP keepalives. If you are unable to enable keepalives here are some other options you might like to consider:

    1. If it is in your control, reconfigure the firewall/router which is dropping the connection so that it will not do so for Postgresql client connections

    2. At an application level, you might be able to send some traffic that will keep the DB handles active - for example sending a statement such as SELECT 1; every hour or so. If your programming environment provides connection caching (from the comments I gather it does) then this might be tricky.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型