ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

Unicorn の Metrics

Rails で使われているアプリケーションサーバUnicorn

bogomips.org

Master Process から fork して Worker Process が実際の処理を行う。

Unicorn Worker Killer

一定回数以上リクエストがくるか、一定量以上のメモリを使用した場合、Worker Process を再起動する君。

github.com

設定

config/unicorn.rb

  • worker_processes: Worker Process の数
  • timeout: timeoutの秒数

prometheus_exporter

Metrics を取得するため、prometheus_exporter を読み込んでいる。

github.com

同僚の takeyama さんの記事

qiita.com

コードをみてみる。

prometheus_exporter/lib/prometheus_exporter/instrumentation/unicorn.rb

github.com

指定された frequency で pid_file から pid を取得して unicorn_collector.collect で metrics を取得して json で返す。

collect_unicorn_stats でとっているのは以下3つ。

  • metric[:active_workers_total] = stats.active
  • metric[:request_backlog_total] = stats.queued
  • metric[:workers_total] = worker_process_count

worker_process_count は直後の private method で定義されている通りで、単純に pgrep で取ってきている。

      result = `pgrep -P #{pid} -f unicorn -a`
      result.lines.count

stats というのがどこからくるかというと listener_address_stats という private method からきていて、tcp であれば Raindrops::Linux.tcp_listener_stats([@listener_address])[@listener_address] を返している。

Raindrops

はてさて Raindrops とは何か。

bogomips.org

raindrops is a real-time stats toolkit to show statistics for Rack HTTP servers. It is designed for preforking servers such as unicorn, but should support any Rack HTTP server on platforms supporting POSIX shared memory. It may also be used as a generic scoreboard for sharing atomic counters across multiple processes.

ほー。

というわけで

Prometheus Exporter で取れる 3つの Metrics は以下

github.com

  • workers_total: 'Number of unicorn workers.',
  • active_workers_total: 'Number of active unicorn workers',
  • request_backlog_total: 'Number of requests waiting to be processed by a unicorn worker.'

active ってのは実際に処理をしているってことなのかな?queued は unicorn に処理されるのを待っているリクエストの数。

request_backlog_total が高い状態が続いた場合、Timeout となってしまいそうだ。

どう解決すればいいのか

  • Unicorn の Pod の Replicas そのものを増やす?
  • Unicorn の Worker 数を増やす?
  • 時間がかかっている処理を高速化する?

Horizontal Pod Autoscaler の Custom Metrics でいけないかな?と思ってググったけどたどり着けず。

kubernetes.io

その他の Metrics

内製の gem が送っているやつがあるようだ。

/proc/pid/stats の cpu time をもってきて、毎秒比較し、それが変化していなければ idle と判定しており、そのほかの metrics はそれに基づいて計算している。 その結果をDatadog に送るもの。

おわりに

request_backlog_total がしばしば増えていて、それによって エラーも出ているようなのでまずは Metrics の理解が大事だと思ったのでいろいろみてみた。勉強になった。さてどうしよう。