LoginSignup
171
169

More than 5 years have passed since last update.

fluentdで本番環境を再現する

Last updated at Posted at 2015-05-19

toyama0919/fluent-plugin-http_shadowというShadow Proxyっぽいことを簡単にやるプラグインを作りました。
production環境で半年くらい動かしてたのでメモしときます。

「Fluentd Meetup 2015 夏」で実際のユースケースを発表しました。

Shadow Proxyサーバとは

Shadow Proxyサーバについては以下がわかりやすいです。

実装としては以下のようなものが公開されています。

本番のリクエストをそのままバックエンドにあるサーバーに複製して送信するのですが、アプリケーションの規模が大きくなればなるほど効果を発揮します。
規模が大きくなればなるほどテスト方法も複雑になってきます。

現在本番で発生しているrequestをそのまま持ってくることで、限りなく本番に近い状態を再現できます。
Shadow Proxy代表的なユースケースとしては負荷試験や結合試験になります。

これをもう少し簡単かつ安全に出来ないかと考え、fluentdで実現してみました。

概要

fluentdに送信されるログからhttp requestを復元しています。

fluent-plugin-http_shadow

Proxyは使わないので、本番のWEBサーバーには影響なく導入出来ます。

設定例(Apache等)

<source>
  type tail
  format ltsv
  time_key log_time
  time_format %d/%b/%Y:%H:%M:%S %z
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/access.pos
  tag http_shadow.example
</source>

ログフォーマット例

  {
    "host": "exsample.com",
    "ip_address": "127.0.0.1",
    "server": "10.0.0.11",
    "remote": "-",
    "time": "22/Dec/2014:03:20:26 +0900",
    "method": "GET",
    "path": "/hoge/?id=1",
    "code": "200",
    "size": "1578",
    "referer": "http://exsample.com/other/",
    "user_agent": "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko"
  }

設定はこう

<match http_shadow.example>
  type http_shadow
  host_hash { 
    "www.example.com": "staging.example.com", 
    "api.example.com": "api-staging.example.com", 
    "blog.ipros.jp": "blog-staging.ipros.jp"
  }
  host_key host
  path_format ${path}
  method_key method
  header_hash { "Referer": "${referer}", "User-Agent": "${user_agent}" }
  max_concurrency 10
  flush_interval 10
  timeout 10
  rate 10
</match>
  • host_hashでVirtual Hostに対応できます。

    • Host名に対応したrequest先を定義します。
  • rateが10の場合、requestが10%に希釈されます。(残りの90%は破棄される)

    • ステージング環境が本番環境よりも低いスペックの場合などはrateを調節します
  • header_hashでhttp headerを指定できます。

    • ${referer}のようにplaceholderでkeyを指定。
    • 固定文字列も可能です。
  • apacheのログの場合、postのパラメータはないので欠損します。

設定例2(アプリ内で専用のログを作れる場合、Railsとか)

アプリケーションから以下のようなログを出す場合、

  {
    "host": "example.com",
    "ip_address": "127.0.0.1",
    "log_time":"2015-05-18 16:38:14",
    "method": "GET",
    "path": "/hoge/",
    "uuid": "e78407cf040f67d17361281906895ca1283929e33592f81cdbda54a4a24e8cf7",
    "session_id": "42d0c906bfde8a30d323865d82a234abb4d13db80471d3b0bf4b7adc515d06da903f514289340ca17ba5cedde118868deebe53ef3986bfae8b591b9a614f7242",
    "user_id": 1
    "params": {"utf8"=>"✓", "client_id"=>"384809"} ,
    "referer": "http://exsample.com/other/",
    "user_agent": "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko"
  }

設定例

<match http_shadow.exsample>
  type http_shadow
  host_hash { 
    "example.com": "staging.example.com"
  }
  host_key host
  path_format ${path}
  method_key method
  header_hash { "Referer": "${referer}", "User-Agent": "${user_agent}" }
  cookie_hash {"rails-app_session": "${session_id}"}
  params_key params
  max_concurrency 10
  flush_interval 10
  timeout 10
  rate 10
</match>
  • cookie_hashでcookieを送信も送信可能です。

    • 設定方法はheader_hashと同じ
  • getやpostのパラメータはparams_keyの中にhashで格納しておけばパラメータをmergeします。

パラメータ

設定可能な値とデフォルト値

  config_param :host, :string, :default => nil
  config_param :host_key, :string, :default => nil
  config_param :host_hash, :hash, :default => nil
  config_param :path_format, :string
  config_param :method_key, :string, :default => nil
  config_param :header_hash, :hash, :default => nil
  config_param :cookie_hash, :hash, :default => nil
  config_param :params_key, :string, :default => nil
  config_param :max_concurrency, :integer, :default => 10
  config_param :timeout, :integer, :default => 5
  config_param :username, :string, :default => nil
  config_param :password, :string, :default => nil
  config_param :rate, :integer, :default => 100

詳細

設定値 内容
host httpリクエストを送信するhost名
host_key Virtual Hostの際の接続Hostのキー
host_hash Virtual Hostの際の接続Hostのペア
path_format urlのpathのフォーマット。${path}などでテンプレート化
method_key http methodが定義されたキー。デフォルトはGET
header_hash http headerのペア
cookie_hash cookieのペア
params_key parameterが格納されたhashのkey
max_concurrency httpリクエストの並列数
timeout タイムアウト時間(秒)
username Basic認証のユーザー名
password Basic認証のパスワード
rate HTTPリクエストの希釈率。デフォルトが100で全てのリクエストがそのまま送信される。50ならば半分のリクエストが送信される。
171
169
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
171
169