2

Rails アプリに対して 4 つの Unicorn プロセスを実行すると、使用可能なすべての MySQL 接続が消費され、「接続が多すぎます」というエラーで崩壊します。今日、DB インスタンスを 4 回再起動する必要がありました。=(

プロセス

$ ps 斧 | grep [u]ni
21618 ? Sl 0:15 ユニコーンマスター -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                           
21632 ? Sl 0:20 ユニコーン ワーカー[0] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21636 ? Sl 0:14 ユニコーン ワーカー[1] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21640 ? Sl 0:20 ユニコーン ワーカー[2] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production                                                        
21645 ? Sl 0:12 ユニコーン ワーカー[3] -D -c /home/deployer/apps/XXX/shared/config/unicorn.rb -E production  

私のdatabase.ymlは、ActiveRecord プール用に 22 の接続を設定しています...

...
製造:
  アダプター: mysql2
  エンコーディング: utf8
  データベース: xxx
  ユーザー名: xxx
  パスワード: xxx
  ホスト: xxx
  ポート: 3306
  プール: 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"

「/tmp/unicorn.XXX.sock」を聞く
worker_processes 4
タイムアウト 100

preload_app 真

before_fork do |サーバー、ワーカー|
  # データベース接続が引き継がれないので切断
  定義されている場合は?ActiveRecord::ベース
    ActiveRecord::Base.connection.disconnect!
  終わり

  # 古いユニコーンのプロセスをやめる
  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    始める
      Process.kill("QUIT", File.read(old_pid).to_i)
    Errno::ENOENT、Errno::ESRCH のレスキュー
      # 他の誰かが私たちの仕事をしてくれました
    終わり
  終わり
終わり

after_fork do |サーバー、ワーカー|
  # ワーカーでデータベース接続を再起動します
  定義されている場合?(ActiveRecord::Base)
    ActiveRecord::Base. Establish_connection
  終わり
  child_pid = server.config[:pid].sub(".pid", ".#{worker.nr}.pid")
  system("echo #{Process.pid} > #{child_pid}")
終わり

DB コンソールを見ると、次のように表示されます。彼らは接続のほとんどを食べました。(今はユニコーンしか動いていませんでした) 私の考えでは、1 つの接続 * 4 つのユニコーン = 4 つの接続があるはずでした。

mysql> 完全なプロセスリストを表示します。
+-----+----------------------+-------------------------------- --------------+----------------------------+------ ---+------+-------+-----------------------+
| | ID | ユーザー | ホスト | ホスト デシベル | コマンド | 時間 | 状態 | 情報 |
+-----+----------------------+-------------------------------- --------------+----------------------------+------ ---+------+-------+-----------------------+
| | 2 | rdsadmin | ローカルホスト:31383 | ヌル | 睡眠 | 9 | | | ヌル |
| | 52 | レベル | 212.100.140.42:50683 | レベルトラベルプロダクション | クエリ | 0 | ヌル | 完全なプロセスリストを表示 |
| | 74 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38197 | レベルトラベルプロダクション | 睡眠 | 5 | | | ヌル |
| | 75 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38199 | レベルトラベルプロダクション | 睡眠 | 8 | | | ヌル |
| | 76 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38201 | レベルトラベルプロダクション | 睡眠 | 8 | | | ヌル |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ カット ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

| | 157 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38321 | レベルトラベルプロダクション | 睡眠 | 154 | | | ヌル |
| | 158 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38322 | レベルトラベルプロダクション | 睡眠 | 17 | | | ヌル |
| | 159 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38325 | レベルトラベルプロダクション | 睡眠 | 54 | | | ヌル |
| | 160 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38326 | レベルトラベルプロダクション | 睡眠 | 54 | | | ヌル |
| | 161 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38327 | レベルトラベルプロダクション | 睡眠 | 54 | | | ヌル |
| | 162 | レベル | ip-10-55-10-151.eu-west-1.compute.internal:38329 | レベルトラベルプロダクション | 睡眠 | 42 | | | ヌル |
+-----+----------------------+-------------------------------- --------------+----------------------------+------ ---+------+-------+-----------------------+
セットで 90 行 (0.15 秒)

この問題の背景については、sidekiq リポジトリの Issue #503 も参照してください。 https://github.com/mperham/sidekiq/issues/503

4

1 に答える 1

9

4つのユニコーンプロセスを実行しました。それはプロセスであり、スレッドではありません。
すべてのプロセスには、プール内に22の接続があります。合計で22*4=88の接続があります。
4つのワーカープロセスに対して4つの接続が必要な場合は、database.ymlでプールを1に設定できます。

于 2012-11-14T20:05:00.767 に答える