2016-04-08 10 views
1

Ich bin gerade dabei, einige Posgres Verbindungslecks in unserer Anwendung zu debuggen. Vor ein paar Tagen haben wir plötzlich 100 Verbindungen geknackt, als wir nicht sein sollten - denn wir haben nur 8 Einhornarbeiter und einen Sidekiq-Prozess (25 Threads).Große Anzahl von Threads unter Einhorn

Ich schaute heute auf htop und sah, dass eine Tonne Fäden von meinen Einhorn-Arbeitern hervorgebracht wurden. ZB:

enter image description here Liest ich das richtig? Das sollte nicht richtig passieren? Wenn diese Threads erzeugt werden, irgendeine Idee, wie man das debuggt?

Danke! Btw, mein anderes Problem - (Postgres Verbindungen) Debugging unicorn postgres connection leak

EDIT

Ich folgte nur ein paar Tipps hier - http://varaneckas.com/blog/ruby-tracing-threads-unicorn/ - und wenn ich den Stack-Trace von den Gewinden Arbeiter gedruckt, hier ist, was ich habe wenn es viele Threads ..

[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] ------------------- 

Das ist mein unicorn.rb https://gist.github.com/steverob/b83e41bb49d78f9aa32f79136df5af5f und es erzeugt einen Thread für eventmachine in after_fork.

Der Grund für diese ist eventmachine ->https://github.com/keenlabs/keen-gem#asynchronous-publishing

ist das normal? Sollten die Fäden nicht getötet werden? Könnte dies auch dazu führen, dass nicht benötigte db-Verbindungen geöffnet sind? Dank

UPDATE: ich gerade herausgefunden, dass ich eine ältere Version des PubNub gem bin mit der EM verwendet und ich lief in diese Zeilen in der pubnub.log Datei -

D, [2016-04-06T21:31:12.13#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 
+0

Ich denke auch nicht, dass das normal ist. Vielleicht benutzen Sie 'Thread' in Ihrem Anwendungscode? Könnten Sie versuchen, das hier beschriebene Verfahren [http://vananeckas.com/blog/ruby-tracing-threads-unicorn/] zu verwenden, um Stack-Traces von den Einhorn-Threads zu erhalten (siehe insbesondere das _Was Ruby an einem beliebigen Punkt ausführt) Moment? _ Abschnitt)? Auf diese Weise können Sie herausfinden, wo die Threads verweilen. – BoraMa

+0

Wow. Danke für diesen Link @BoraMa –

+0

Ich denke, Sie haben 'reaper_frequency' in Ihrer' database.yml' konfiguriert, so dass der mittlere Thread der [Reaper thread] ist (https://github.com/rails/rails/blob/master/activerecord /lib/active_record/connection_adapters/abstract/connection_pool.rb#L300) und ich denke es ist normal. Wir sollten warten, bis sich die Fäden angesammelt haben ... – BoraMa

Antwort

1

So Schließlich scheint das Verhalten in Ihrem speziellen Fall normal zu sein.

Die von Ihnen bereitgestellten Einhorn-Threads (die mit this method erhalten wurden) zeigen auf the spawn_threadpool method in EventMachine. Dieser Code in der EventMachine wird aufgerufen, wenn ein anderer Code EventMachine.defer aufruft, eine Methode, die spawns einen Pool von 20 Threads beim ersten Aufruf standardmäßig aufruft. Ich fand Verwendung von EventMachine.defer in einer älteren Version des pubnub Gems (z. B. here), aber es kann auch von anderen Orten verwendet werden.

Also, ich denke, dies erklärt das hohe Volumen von Threads Sie auf jeden Arbeiter zu beobachten. Sie warten meistens in der pop method, die den Thread aussetzt, bis etwas in die Warteschlange geschoben wird (erneut in EventMachine verschoben). Wenn Sie also keine hohe Anzahl von verzögerten Operationen haben, tun die Threads meistens nichts.

Wenn Sie auf jedem Einhorn Arbeiter bereit für aufschiebbare Operationen (die meisten wahrscheinlich Sie nicht) nicht mehr als 20 Threads haben müssen, können Sie, indem Sie die threadpoolsize variable die Anzahl der Threads im Pool zu niedriger versuchen zu einer vernünftigen Anzahl, z:

EventMachine.threadpool_size = 5 

ich diese irgendwo im after_fork Block in Einhorn Config setzen würde.

Als weitere Option könnten Sie die unicorn-worker-killer gem verwenden, um die Mitarbeiter von Einhörnern regelmäßig zu töten.

Übrigens scheinen die Meldungen, die pubnub in sein Protokoll spuckt, in Ordnung zu sein, da es nur sagt, dass es einen bereits initialisierten EventMachine-Thread gefunden hat, so dass er keinen neuen starten muss. This source code klärt es.

+0

Super genial !!!! Ich kann dir nicht genug danken, dass du so viel Zeug geteilt hast. :) :) Wenn es nicht zu unhöflich ist, ist es möglich, dass Sie meine andere Ausgabe auschecken - http://StackOverflow.com/questions/36484097/debugging-unicorn-postgres-connection-leak danke :) –

+0

OK, versucht zu antworte dort auch :) – BoraMa

Verwandte Themen