我爲每個服務器運行10個Unicorn工作人員,隨着時間的推移他們吃掉了所有MySQL連接,最終導致「連接太多」錯誤。它從10個連接開始,但逐漸增加到20個。獨角獸和Rails吃掉了2個MySQL連接
當我在生產上運行以下腳本(使用SHOW PROCESSLIST
)時,我可以看到每個IP(=應用程序服務器)每個都有20個連接, 10 - 令人羨慕的是獨角獸工人數量的兩倍。
result = ActiveRecord::Base.connection.execute 'show processlist'
result.group_by{|i| i[2].split(':').first }.map{|k,v| [k, v.size] }
=> [["192.168.1.2", 20], ["192.168.1.3", 20], ["192.168.1.4", 20], ... ]
這裏的database.yml中
production:
adapter: mysql2
...
pool: 1
下面是使用netstat:
# netstat -an | grep :3306
tcp 0 0 192.168.1.2:58535 192.168.1.123:3306 ESTABLISHED
tcp 0 0 192.168.1.2:45021 192.168.1.123:3306 ESTABLISHED
tcp 0 0 192.168.1.2:58537 192.168.1.123:3306 ESTABLISHED
tcp 0 0 192.168.1.2:45119 192.168.1.123:3306 TIME_WAIT
...
# netstat -an | grep :3306 | wc -l
36
# netstat -an | grep :3306 | grep ESTABLISHED | wc -l
33
我擔心,有幾個TIME_WAIT
- 它不應該存在的連接應都是持久的 - 看起來工人有更多的聯繫。大量的免費RAM,無需交換/ OOM。
Ruby 2.0.0p0/Rails 3.2.13
這是什麼原因造成的?
我在New Relic的Ruby代理上工作,並想讓我們知道我們在上一版本(昨天發佈的3.6.0.78)中改進了這種行爲。在某些分叉網絡服務器(如Unicorn,Passenger)下,這些數據庫連接沒有被正確清理的問題。我們已經證實,情況已經不復存在。我認爲你關於不尊重連接池設置的觀點可能依然存在。在某些情況下(例如,應用程序通過不同的適配器與多個dbs對話)使得這很難做到,但這是我們將在下一個版本中考慮的事情。 – samg 2013-03-21 19:56:26
我更新了我的寶石到3.6.0.78,並檢查連接數沒有變化。再次有很多連接到MySQL。我正在使用獨角獸。 – anshuman 2013-03-26 13:12:30
3.6.0.78爲我解決了這個問題。它仍然會建立連接,只是適當地關閉它們。如果同時有很多緩慢的查詢,則會有多達2個連接。爲了解決這個問題,New Relic需要支持連接池。 – kenn 2013-03-26 17:09:05