新手问题 [已解决] Rails.logger 内部有锁吗?

xiaoronglv · 2015年02月01日 · 最后由 lyfi2003 回复于 2015年02月01日 · 2467 次阅读

最近在看《Working with ruby thread》这本书,内容超级赞!在读的时候遇到一个问题,Google 之后依然无果。因为我的计算机基础差,好多底层的东西不了解。

问题是这样的:

  • Rails.logger 是个 singleton 对象。
  • 记录 log 是 IO 操作,MRI 允许并行。

假如我用 puma 起了 1 个进程,32 个线程。

  1. 问题 1:在并发量比较大的时候,32 个线程会出现同时往 Rails.logger 中写东西的情况吗?

  2. 问题 2:Rails.logger 内部有互斥锁来保证线程安全吗?

不保证, 默认情况下 Rails 只是用 Ruby 自带的 Logger 库来记录日志.

你可以自行修改 config/environments/production.rb 里面的 logger 来达到你的要求.

是线程安全的。楼主可以看 ruby 自带库里的 logger 源码

@zhangyuan 嗯, 刚 pry 跟了下, 确实是线程安全的:

# From: /Users/yafeilee/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/logger.rb @ line 558 Logger::LogDevice#write:

    557: def write(message)
 => 558:   begin
    559:     @mutex.synchronize do
    560:       if @shift_age and @dev.respond_to?(:stat)
    561:         begin
    562:           check_shift_log
    563:         rescue
    564:           warn("log shifting failed. #{$!}")
    565:         end
    566:       end
    567:       begin
    568:         @dev.write(message)
    569:       rescue
    570:         warn("log writing failed. #{$!}")
    571:       end
    572:     end
    573:   rescue Exception => ignored
    574:     warn("log writing failed. #{ignored}")
    575:   end
    576: end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号