[erlang]高および下のログ出力テクニック

1675 ワード

前言


以前、会社は圧力テストの概念を導入し、tsungテストを使って高いサービスの性能を発揮した.このテストでは、元のlager:info法の弊害が明らかになった.テストサービスは、ログを1回印刷する場合、空回りの1/6にパフォーマンスを低下させる.

探究する


ログの本質は、実は/opt/app/logディレクトリの下に横たわっているファイルです.マルチスレッド方式でエントリのボトルネックを回避したが、同じリソースにアクセスする必要がある場合、ボトルネックがまた現れた.我々の実装ではロックは発生していないが、実際のロックは存在する.では、少し基礎的な読者は問題の解決策を理解すべきだと信じています.ノードにメッセージを送り、メールボックスの受信方式でソートし、同時をシリアルに変え、ロックの問題を解決します.

じっけん


サービス(cowboy)が起動したときに新しいノードを開き、ノードをpid_に登録します.lager
true = register(pid_lager, spawn(tools, log, []))

ログを打つ必要がある場合は、ログの情報をlager_に送信します.pidノード
tools:lager_log(info, <>)

ノードは情報を受け取って印刷処理を行う
log() ->
  receive
    {info, Msg} ->
      lager:info(Msg),
      log();
    {info, Format, Data} ->
      lager:info(Format, Data),
      log();
    {warning, Msg} ->
      lager:warning(Msg),
      log();
    {warning, Format, Data} ->
      lager:warning(Format, Data),
      log();
    {error, Msg} ->
      lager:error(Msg),
      log();
    {error, Format, Data} ->
      lager:error(Format, Data),
      log();
    _ ->
      log()
  end.
lager_log(Level, Msg) when Level =:= info orelse Level =:= warning orelse Level =:= error ->
  pid_lager ! {Level, Msg}.
lager_log(Level, Format, Data) when Level =:= info orelse Level =:= warning orelse Level =:= error ->
  pid_lager ! {Level, Format, Data}.

結果


競合を解消する場合、ログによる損失は約数ポイントのパフォーマンス損失である.しかし、単位時間当たりの出力ログに上限があり、毎秒1 wの圧力で6000件以上のログしか打てないという欠点がある.残りのログは、圧力テストの終了後も運転を継続する出力される.これは私には良い方法がありません.ログを簡素化し、サービスをバックアップし、複数の方法を導入してストレスを緩和することしか考えられません.