ken*_*enn 2 mysql activerecord ruby-on-rails unicorn
我为每个服务器运行10个Unicorn工作程序,随着时间的推移他们吃掉所有MySQL连接,结果是"连接太多"错误.它从10个连接开始,但逐渐增加到20个.
当我在生产(使用SHOW PROCESSLIST)上运行以下脚本时,我可以看到每个IP(=应用程序服务器)每个都有20个连接,它应该是10 - 令Unicorn worker的数量增加了两倍.
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], ... ]
Run Code Online (Sandbox Code Playgroud)
这是database.yml
production:
adapter: mysql2
...
pool: 1
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
我担心会有一些TIME_WAIT- 它不应该存在,因为连接应该都是持久性的 - 似乎工作者有更多的连接而不是必要的.大量的空闲RAM,没有交换/ OOM.
Ruby 2.0.0p0/Rails 3.2.13
是什么导致了这个?
好的,感谢@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
Run Code Online (Sandbox Code Playgroud)
问题已经解决了!我会保持这种方式,直到New Relic解决了这个问题.
| 归档时间: |
|
| 查看次数: |
1175 次 |
| 最近记录: |