我为每个服务器运行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