当前位置: 首页 > 知识库问答 >
问题:

独角兽吞噬MySQL连接不尊重池大小-Rails

汪同
2023-03-14

我为Rails应用程序运行了4个Unicorn进程,它们耗尽了所有可用的MySQL连接,导致其崩溃,出现“连接太多”错误。今天我不得不重新启动我的DB实例4次=(

过程

$ 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正在为ActiveRecords池设置22个连接...

...
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个连接。

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

共有1个答案

颜志业
2023-03-14

您已经运行了4个unicorn进程。这是过程,而不是线程
池中每个进程有22个连接。总共有22个*4=88个连接
若要为4个工作进程建立4个连接,可以在数据库中设置池:1。yml公司

 类似资料:
  • 在我的程序中,我正在访问wep api。最多可以有7个不同的线程访问web api的不同服务器。每个线程负责一个服务器,每个服务器速率限制每个线程。每个线程更新相同的mysql数据库。线程数保持不变。 在我的示例中,是否需要连接池?我不应该只打开7个不同的连接,这些连接将在程序的生命周期中打开吗?

  • 嘿,我正在使用Glassfish开源v4,我遇到了一个奇怪的问题。 我在管理控制台中定义了到Oracle 11g的JDBC连接池,并设置了: 初始和最小池大小:500 最大游泳池大小:1000 池大小调整数量::750 我已经为这个连接池创建了一个特定的用户。然而,有时当我检查数据库中打开的连接时,我发现有1000多个连接(我看到的最大连接数是1440个) 当发生这种情况时,任何查询尝试都会失败,

  • 问题内容: 我有这样的字符串。 我想将其拆分以获取以下输出。\ $是转义的$,因此应将其保留在输出中。 但是,当我做 ÿ得到。 从我得到的正则表达式匹配a $和i $然后删除。关于如何找回角色的任何想法吗? 谢谢 问题答案: 使用零宽度匹配断言: 正则表达式本质上是 它使用负向后看来断言没有在前。 也可以看看 Regular-expressions.info/解决方法 断言分裂的更多示例 简单的句

  • 问题内容: 为什么在hibernate配置文件中为连接池设置10?size = 1是内置的size。为什么需要增加大小? 问题答案: 来自Hibernate API 文档。 但是,Hibernate自己的连接池算法非常初级。它旨在帮助您入门,不适合在生产系统中使用,甚至不用于性能测试。您应该使用第三方池来获得最佳性能和稳定性。只需将hibernate.connection.pool_size属性替

  • 我目前正在使用okhttp 3.10.0,我最近才发现,为每个新请求创建一个新的客户端对每个拥有自己连接池的客户端都是有害的。 我在servlet中使用okhttp。我现在要做的就是在每个servlet中声明一个静态客户机,并在init()方法中初始化它 这里是最大空闲连接的配置,我将其设置为20,空闲超时设置为5分钟。 1)实际的池大小是多少,即池将具有的最大连接(通过代码查看,我发现它可能是I

  • 在OkHttp中,我找不到设置硬最大连接池大小的方法。从留档https://square.github.io/okhttp/3.x/okhttp/okhttp3/ConnectionPool.html很明显,您可以设置最大空闲连接,但不能设置整体最大值。这意味着在高负载下,它可以增长超过任何限制。 有没有办法最大化池?如果没有,为什么没有?