3

私たちのアプリケーションでいくつかの Posgtres 接続リークをデバッグ中です。数日前、あるべきではないときに突然 100 接続を超えました。8 つのユニコーン ワーカーと sidekiq プロセス (25 スレッド) しかないからです。

今日 htop を見ていたら、ユニコーン ワーカーから大量のスレッドが生成されていることがわかりました。例えば:

ここに画像の説明を入力 私はこれを正しく読んでいますか?これは起こってはいけませんよね?これらが生成されているスレッドである場合、これをデバッグする方法はありますか?

ありがとう!ところで、私の他の問題 - (Postgres 接続) Unicorn postgres 接続リークのデバッグ

編集

ここでいくつかのヒントに従いました- http://varaneckas.com/blog/ruby-tracing-threads-unicorn/ -そして、ワーカーのスレッドからスタックトレースを出力したとき、多くのスレッドがあるときに得たものは次のとおりです..

[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `pop'
[17176] /u/apps/eventstream_production/shared/bundle/ruby/2.2.0/gems/eventmachine-1.0.8/lib/eventmachine.rb:1057:in `block in spawn_threadpool'
[17176] ---
[17176] -------------------

これは私の unicorn.rb https://gist.github.com/steverob/b83e41bb49d78f9aa32f79136df5af5fであり、after_fork で EventMachine のスレッドを生成します。

EventMachine の理由はこれです --> https://github.com/keenlabs/keen-gem#asynchronous-publishing

これは正常ですか?スレッドを殺すべきではありませんか?これにより、不必要なデータベース接続が開かれる可能性もありますか? ありがとう

更新: EM を使用する古いバージョンの PubNub gem を使用していることがわかりました。pubnub.log ファイルでこれらの行に遭遇しました -

D, [2016-04-06T21:31:12.130123 #1573] DEBUG -- pubnub: Created event Pubnub::Publish
D, [2016-04-06T21:31:12.130144 #1573] DEBUG -- pubnub: Pubnub::SingleEvent#fire
D, [2016-04-06T21:31:12.130162 #1573] DEBUG -- pubnub: Pubnub::SingleEvent#fire | Adding event to async_events
D, [2016-04-06T21:31:12.130178 #1573] DEBUG -- pubnub: Pubnub::SingleEvent#fire | Starting railgun
D, [2016-04-06T21:31:12.130194 #1573] DEBUG -- pubnub: Pubnub::Client#start_event_machine | starting EM in new thread
D, [2016-04-06T21:31:12.130243 #1573] DEBUG -- pubnub: Pubnub::Client#start_event_machine | We aren't running on thin
D, [2016-04-06T21:31:12.130264 #1573] DEBUG -- pubnub: Pubnub::Client#start_event_machine | EM already running
4

2 に答える 2

5

したがって、結局のところ、特定のケースでは動作は正常であるように見えます。

あなたが提供したユニコーン スレッド スタック トレース (このメソッドを使用して取得)は、 EventMachinespawn_threadpoolメソッドを指しています。EventMachine のこのコードは、他のコードが最初の呼び出しでデフォルトで 20 個のスレッドのプールを生成EventMachine.deferするメソッドを呼び出すときに呼び出されます。古いバージョンのgem (例: here ) で の使用法を見つけましたが、他の場所から使用することもできます。EventMachine.deferpubnub

したがって、これは、各ワーカーで観察される大量のスレッドを説明していると思います。ほとんどの場合、何かがキューにプッシュされるまでスレッドを一時停止するpopメソッドで待機します (EventMachine で再び延期されます)。したがって、遅延操作の負荷が高くない限り、スレッドはほとんど何もしていません。

遅延可能な操作のために各ユニコーン ワーカーに 20 のスレッドを準備する必要がない場合 (ほとんどの場合必要ありません)、変数を適切な数に設定することで、プール内のスレッドの数を減らすthreadpoolsizeことができます。 :

EventMachine.threadpool_size = 5

after_forkこれをユニコーン構成のブロックのどこかに配置します。

また、別のオプションとして、unicorn-worker-killer gemを使用して定期的にユニコーンのワーカーを殺すことを検討することもできます。

ちなみに、pubnubログに吐き出されるメッセージは問題ないようです。既に初期化された EventMachine スレッドが見つかったことを示しているだけなので、新しいスレッドを開始する必要はありません。このソースコードはそれを明確にします。

于 2016-04-09T07:06:17.060 に答える