0

我想为我编写简单的记录器,将消息放入内存中,并在后台每隔 X 秒将其写入数据库。

这是缓冲的记录器代码:

module BufferedLogger
  def buffer
    @buffer ||= []
  end

  def log( message )
    buffer << message
  end

  def write_buffer  
    while message = buffer.shift do 
      # save the message in nosql
    end
  end

  def repeat_every( interval )
    Thread.new do
      loop do
        start_time = Time.now
        yield
        elapsed = Time.now - start_time
        sleep([interval - elapsed, 0].max)
      end
    end
  end

  extend self

  thread = repeat_every(10) do
    write_buffer
  end 

end

在开发中,这很好用,可以在和方法中buffer()访问相同@buffer的变量。但是一旦我进入生产或登台环境,即一旦我落后于乘客,这似乎不再被共享。logwrite_buffer@buffer

任何指针?

4

2 回答 2

1

由于passenger创建单独的流程,并且这些流程将如何持续取决于乘客的算法,我想它不会像您期望的那样运作良好。(顺便说一句,我在这方面使用全局变量/类变量的经验很糟糕。)

我对缓冲日志的建议是,使用像fluentd这样的记录器作为中间处理器。Fluentd 可以监控和收集日志。您可以编写一个插件将收集的日志写入数据库。我认为这将满足您的需求。

于 2012-09-26T20:59:42.483 回答
0

如果您尝试保存数据库 I/O,这通常不是问题,因此您可能会过早地进行优化。

如果我需要缓冲数据库写入,我可能会关闭自动提交,然后在记录发生时写入记录,在 n 条记录后或 n 秒后提交,以先到者为准。

数据库可以处理大量流量并具有各种内部缓冲,因此您的磁盘和系统影响最小化。如果您的数据库与 Rails 主机在同一台机器上,那么出于性能原因,您应该将它们分开。

否则,除非您收集了指标并且可以指出数据库 I/O 存在问题,否则我会说编写代码并且在问题浮出水面之前不必担心缓冲。

于 2012-09-26T21:49:11.283 回答