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

開発中、これは正常に機能し、メソッドとメソッドの両方で同じ var にbuffer()アクセスします。しかし、本番環境またはステージング環境に移動するとすぐに、つまり乗客の後ろにいるとすぐに、これはもう共有されていないようです。@bufferlogwrite_buffer@buffer

ポインターはありますか?

4

2 に答える 2

1

別のプロセスを作成し、これらpassengerのプロセスがどのように存続するかは乗客のアルゴリズムに依存するため、期待どおりに機能しないと思います。(ところで、グローバル変数/クラス変数を使用して、この点で悪い経験がありました。)

ログをバッファリングするための私の提案は、fluentdのようなロガーを中間プロセッサとして使用することです。Fluentd は、ログを監視および収集できます。収集したログを DB に書き込むプラグインを作成できます。これはあなたのニーズに合うと思います。

于 2012-09-26T20:59:42.483 に答える
0

データベース I/O を節約しようとしている場合、通常は問題にならないため、時期尚早に最適化している可能性があります。

データベースの書き込みをバッファリングする必要がある場合は、おそらく自動コミットをオフにしてから、レコードが発生したときにレコードを書き込み、n レコード後または n 秒後のいずれか早い方でコミットします。

データベースは大量のトラフィックを処理でき、あらゆる種類の内部バッファリングも備えているため、ディスクとシステムへの影響が最小限に抑えられます. データベースが Rails ホストと同じマシン上にある場合は、パフォーマンス上の理由からそれらを分割する必要があります。

それ以外の場合は、メトリックを収集し、問題としてデータベース I/O を指摘できる場合を除き、問題が表面化するまではコードを記述し、バッファリングについて心配する必要はありません。

于 2012-09-26T21:49:11.283 に答える