2013-03-20 70 views
2

我爲每個服務器運行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

這是什麼原因造成的?

回答

5

好自己的連接,這要歸功於@ono的建議,我發現原因是New Relic代理創建了自己的連接NewRelic::Agent::Database::ConnectionManager#get_connection

https://github.com/newrelic/rpm/blob/3.5.8.72/lib/new_relic/agent/database.rb#L158

此代碼調用ActiveRecord::Base.mysql2_connection,進而調用Mysql2::Client.new,不尊重連接池設置。

時,有慢交易(具有諷刺意味的是,這個代碼重載數據庫甚至更多),只發生,所以編輯newrelic.yml

transaction_tracer: 
    explain_enabled: false 

,問題已經解決了!我會保持這種狀態,直到New Relic修復此問題。

+0

我在New Relic的Ruby代理上工作,並想讓我們知道我們在上一版本(昨天發佈的3.6.0.78)中改進了這種行爲。在某些分叉網絡服務器(如Unicorn,Passenger)下,這些數據庫連接沒有被正確清理的問題。我們已經證實,情況已經不復存在。我認爲你關於不尊重連接池設置的觀點可能依然存在。在某些情況下(例如,應用程序通過不同的適配器與多個dbs對話)使得這很難做到,但這是我們將在下一個版本中考慮的事情。 – samg 2013-03-21 19:56:26

+0

我更新了我的寶石到3.6.0.78,並檢查連接數沒有變化。再次有很多連接到MySQL。我正在使用獨角獸。 – anshuman 2013-03-26 13:12:30

+0

3.6.0.78爲我解決了這個問題。它仍然會建立連接,只是適當地關閉它們。如果同時有很多緩慢的查詢,則會有多達2個連接。爲了解決這個問題,New Relic需要支持連接池。 – kenn 2013-03-26 17:09:05

0

瘋狂猜測,你有一箇中間件,打開連接到你的數據庫服務器?運行$ rake middleware覈實,sidekiq例如你是一個原因,或任何其他coponent需要你的數據庫服務器

+0

好點。我只是跑'耙中間件',但它幾乎是默認的,找不到除Airbrake和NewRelic之外的任何異常。 – kenn 2013-03-20 23:29:34