独角兽吞噬了MySQL连接而不尊重池的大小-Rails [英] Unicorns eat up MySQL connections not respecting the pool size - Rails

查看:55
本文介绍了独角兽吞噬了MySQL连接而不尊重池的大小-Rails的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的Rails应用程序运行了4个Unicorn进程,它们吞噬了所有可用的MySQL连接,导致它因连接过多"错误而崩溃.今天,我不得不重新启动数据库实例4次. =(

I run 4 Unicorn processes for my Rails app and they eat up all the available MySQL connections causing it to collapse with 'too many connections' error. Today I had to reboot my DB instance 4 times. =(

进程


$ ps ax | grep [u]ni
21618 ?        Sl     0:15 unicorn master -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                           
21632 ?        Sl     0:20 unicorn worker[0] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21636 ?        Sl     0:14 unicorn worker[1] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21640 ?        Sl     0:20 unicorn worker[2] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21645 ?        Sl     0:12 unicorn worker[3] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production  

我的 database.yml 正在为ActiveRecord池设置22个连接...

My database.yml is setting up 22 connections for the ActiveRecord pool...


...
production:
  adapter: mysql2
  encoding: utf8
  database: xxx
  username: xxx
  password: xxx
  host: xxx
  port: 3306
  pool: 22
...

Unicorn配置文件如下所示:


working_directory "/home/deployer/apps/XXX/current"
pid "/home/deployer/apps/XXX/shared/pids/unicorn.pid"
stderr_path "/home/deployer/apps/XXX/shared/log/unicorn.log"
stdout_path "/home/deployer/apps/XXX/shared/log/unicorn.log"

listen "/tmp/unicorn.XXX.sock"
worker_processes 4
timeout 100

preload_app true

before_fork do |server, worker|
  # Disconnect since the database connection will not carry over
  if defined? ActiveRecord::Base
    ActiveRecord::Base.connection.disconnect!
  end

  # Quit the old unicorn process
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  # Start up the database connection again in the worker
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end
  child_pid = server.config[:pid].sub(".pid", ".#{worker.nr}.pid")
  system("echo #{Process.pid} > #{child_pid}")
end

如果我们查看数据库控制台,将会看到类似这样的内容.他们已经吃掉了大部分的联系. (目前我只剩下独角兽了.)在我看来,应该有1个连接* 4个独角兽= 4个连接.

And if we look into the DB console, we'll see something like this. They've eaten most of the connections. (I had nothing but Unicorn running at the moment) To my mind there should have been 1 connection * 4 unicorns = 4 connections.


mysql> show full processlist;
+-----+----------+--------------------------------------------------+------------------------+---------+------+-------+-----------------------+
| Id  | User     | Host                                             | db                     | Command | Time | State | Info                  |
+-----+----------+--------------------------------------------------+------------------------+---------+------+-------+-----------------------+
|   2 | rdsadmin | localhost:31383                                  | NULL                   | Sleep   |    9 |       | NULL                  |
|  52 | level    | 212.100.140.42:50683                             | leveltravel_production | Query   |    0 | NULL  | show full processlist |
|  74 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38197 | leveltravel_production | Sleep   |    5 |       | NULL                  |
|  75 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38199 | leveltravel_production | Sleep   |    8 |       | NULL                  |
|  76 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38201 | leveltravel_production | Sleep   |    8 |       | NULL                  |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CUT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

| 157 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38321 | leveltravel_production | Sleep   |  154 |       | NULL                  |
| 158 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38322 | leveltravel_production | Sleep   |   17 |       | NULL                  |
| 159 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38325 | leveltravel_production | Sleep   |   54 |       | NULL                  |
| 160 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38326 | leveltravel_production | Sleep   |   54 |       | NULL                  |
| 161 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38327 | leveltravel_production | Sleep   |   54 |       | NULL                  |
| 162 | level    | ip-10-55-10-151.eu-west-1.compute.internal:38329 | leveltravel_production | Sleep   |   42 |       | NULL                  |
+-----+----------+--------------------------------------------------+------------------------+---------+------+-------+-----------------------+
90 rows in set (0.15 sec)

您也可以查看sidekiq存储库中的问题503,了解此问题的背景 https ://github.com/mperham/sidekiq/issues/503

You may also have a look at Issue #503 in sidekiq repository for the background of this problem https://github.com/mperham/sidekiq/issues/503

推荐答案

您已经运行了4个独角兽进程.这是过程,而不是线程.
每个进程在池中有22个连接.他们总共有22 * 4 = 88个连接.
如果要为4个工作进程建立4个连接,则可以在pool.yml中设置pool:1.

You have run 4 unicorn process. It is the PROCESS, NOT THREAD.
Every process have 22 connections in pool. Totally they have 22*4 = 88 connections.
If you want have 4 connection for 4 worker process, you can set pool: 1 in database.yml

这篇关于独角兽吞噬了MySQL连接而不尊重池的大小-Rails的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆