亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果不使用,數據庫將掛起

如果不使用,數據庫將掛起

Go
LEATH 2021-10-18 17:02:26
我有一個正在啟動的 Web 應用程序。啟動時工作正常,但如果我離開它(例如,一個小時)并用另一個請求點擊它,查詢會掛起。我想在每次查詢后關閉它然后打開一個新連接,但文檔明確說“關閉數據庫很少見,因為數據庫句柄是長期存在的,并在許多 goroutine 之間共享?!?。我究竟做錯了什么?package mainimport (  "database/sql"  "log"  "net/http"  _ "github.com/lib/pq")var Db *sql.DBfunc 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...")}編輯 #1:我的 postgres 日志顯示:2015-07-08 18:10:01 EDT [7710-1] user@here LOG:  could not receive data from client: Connection reset by peer2015-07-08 18:20:01 EDT [7756-1] user@here LOG:  could not receive data from client: Connection reset by peer
查看完整描述

1 回答

?
瀟湘沐

TA貢獻1816條經驗 獲得超6個贊

我也遇到過類似的問題。在我們的案例中,問題是由位于客戶端計算機和數據庫之間的連接跟蹤防火墻引起的。

這樣的防火墻會跟蹤 TCP 級別的連接,并且為了限制資源使用,然后會超時在它們看來長時間不活動的連接。我們在這種情況下觀察到的癥狀與您的非常相似:在客戶端,連接似乎掛起,而在服務器端,您可以看到connection reset by peer.

防止這種情況的一種方法是確保啟用TCP Keepalive,并且 Keepalive 間隔小于導致連接問題的防火墻、路由器等的超時時間。這是由libpq的連接參數控制keepalives,keepalives_idlekeepalives_intervalkeepalives_count您可以在連接字符串中設置。有關這些參數的說明,請參閱手冊。

  • keepalive確定是否啟用keepalive 功能。它默認為1(啟用),因此您可能不需要指定它。

  • keepalives_idle確定發送?;钪暗目臻e時間量。如果不指定此項,它將默認為操作系統的默認值。

    在 Linux 系統中,您可以通過檢查來查看默認值/proc/sys/net/ipv4/tcp_keepalive_time- 在我的服務器中,它設置為 7200 秒,這在您的情況下太長了,因為您觀察到連接在大約 1 小時后斷開。

    您可以嘗試將其設置為 2500 秒。

Linux 文檔項目提供了一個有用的TCP Keepalive HOWTO文檔,其中詳細描述了它們的工作原理。

請注意,并非所有操作系統都支持 TCP keepalive。如果您無法啟用 keepalive,這里有一些您可能需要考慮的其他選項:

  1. 如果它在您的控制之下,請重新配置正在斷開連接的防火墻/路由器,以便它不會對 Postgresql 客戶端連接這樣做

  2. 在應用程序級別,您可能能夠發送一些流量來保持數據庫句柄處于活動狀態 - 例如發送一個語句,例如SELECT 1;每小時左右。如果您的編程環境提供連接緩存(根據我收集的評論),那么這可能會很棘手。


查看完整回答
反對 回復 2021-10-18
  • 1 回答
  • 0 關注
  • 210 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號