Ste*_*son 3 ruby-on-rails eventmachine unicorn pubnub keen-io
我正在调试应用程序中的一些 Posgtres 连接泄漏。几天前,我们突然超过了 100 个连接,而这是不应该的——因为我们只有 8 个独角兽工作线程和一个 sidekiq 进程(25 个线程)。
我今天在查看 htop 时发现我的独角兽工人正在产生大量线程。例如:
我读得正确吗?这不应该发生吧?如果这些是正在生成的线程,知道如何调试它吗?
谢谢!顺便说一句,我的另一个问题 - (Postgres 连接)调试独角兽 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] -------------------
Run Code Online (Sandbox Code Playgroud)
这是我的 unicorn.rb https://gist.github.com/steverob/b83e41bb49d78f9aa32f79136df5af5f,它在 after_fork 中为 EventMachine 生成一个线程。
EventMachine 的原因是这样的 --> https://github.com/keenlabs/keen-gem#asynchronous-publishing
这是正常的吗?线程不应该被杀死吗?这是否也会导致打开不必要的数据库连接?谢谢
更新: 我刚刚发现我正在使用旧版本的 PubNub gem,它使用 EM,并且我在 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
Run Code Online (Sandbox Code Playgroud)
所以,毕竟,在您的特定情况下,这种行为似乎是正常的。
您提供的独角兽线程堆栈跟踪(使用此方法获得)指向EventMachine 中的方法spawn_threadpool。当其他代码调用 时,EventMachine 中的此代码就会被调用EventMachine.defer,该方法在第一次调用时默认生成20 个线程的池。EventMachine.defer我发现在旧版本的gem 中使用了pubnub(例如此处),但它也可以在其他地方使用。
因此,我认为这解释了您在每个工作线程上观察到的大量线程。它们大多在挂起线程pop的方法中等待,直到有东西被推入队列(在 EventMachine 中再次推迟)。因此,除非延迟操作负载很高,否则线程大多不执行任何操作。
如果您不需要每个独角兽工作线程上有 20 个线程准备好延迟操作(很可能您不需要),您可以尝试通过将变量设置为某个合理的数字来减少池中的线程数threadpoolsize,例如:
EventMachine.threadpool_size = 5
Run Code Online (Sandbox Code Playgroud)
我会把它放在after_fork独角兽配置块中的某个地方。
另外,作为另一种选择,您可以考虑使用unicorn-worker-killer gem定期杀死独角兽的工人。
顺便说一句,pubnub吐入其日志的消息似乎没问题,因为它只是告诉我们它找到了一个已经初始化的 EventMachine 线程,因此它不必启动一个新线程。这个源代码澄清了这一点。
| 归档时间: |
|
| 查看次数: |
1764 次 |
| 最近记录: |