2

我为每台服务器运行 10 个 Unicorn 工作人员,随着时间的推移,他们耗尽了所有 MySQL 连接,最终出现“连接太多”错误。开始时有 10 个连接,但逐渐增加到 20 个。

当我在生产环境(使用)上运行以下脚本时SHOW PROCESSLIST,我可以看到每个 IP(= 应用服务器)每个都有 20 个连接,其中应该是 10 - 是 Unicorn 工人数量的两倍。

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 -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。

红宝石 2.0.0p0 / Rails 3.2.13

这是什么原因造成的?

4

2 回答 2

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 解决这个问题之前,我会一直保持这种状态。

于 2013-03-21T18:14:01.720 回答
0

大胆猜测,您是否有一个中间件可以打开与您的数据库服务器的连接?运行$ rake middleware以验证,sidekiq 例如您是一个原因,或任何其他需要自己连接到您的数据库服务器的组件

于 2013-03-20T23:05:57.640 回答