=encoding UTF-8

=head1 NAME

Gungho::Manual::FAQ.ja - Gungho FAQ

=head1 Q. "なんでGungho?"

Gunghoの前段階で開発されたXangoと韻を踏むからです。

=head1 Q. "ドキュメント類内の設定の書式がわかりません"

Gunghoドキュメント内では文中で記しやすいように engine.module = POEのような書式
を使用しています。"."で区切られたそれぞれの項目はハッシュのキーです。例えば
先ほどの engine.module = POEのような場合、実際には以下のような設定を
指しています：

  my $config = {
    engine => {
      module => "POE"
    }
  }

YAMLならばこのようになります

  engine:
    module: POE

=head1 Q. "Gunghoを分散環境で使う事は可能ですか？"

Gunghoは分散環境での動作を可能にするための様々な機能が実装されています。

正確にはそれぞれのクローラーは自分が分散環境で動くように様々な細かい設定を
行う必要があります。Gunghoが提供するのはその解の一例であり、あなたが必要と
する物と１００％合致するとは限りません。その場合はGunghoが提供する部品を
ご覧になった上であなたの環境に合うようにチューニングしてみてください。

Gunghoを分散環境で動作させるにはおおまかに３つの部品を分散化させる必要がありま
す。以下の三つの部品のドキュメントを参照してください。

=over 4

=item 分散スロットリング

Gunghoバージョン0.08010からThrottle::DomainとThrottle::Simpleに対して
Data::Throttlerバックエンドを選択できるようになりました。分散環境に対応する
ためにはスロットリングのバックエンドを分散させる必要があります。このために
Data::Throttler::Memcachedを使用することができます。

Data::Throttler::Memcachedを使用することによって、スロットリングデータを
memcachedに保存し、同じスロットル情報を複数プロセス間で共有する事ができます。

=item robots.txt情報の分散

Gunghoバージョン0.08013からRobotRulesコンポーネントはデータストレージに
BerkeleyDBだけでなくキャッシュを使う事も可能になりました。

こちらも設定にmemcached等の分散キャッシュを使用することによってrobots.txt
情報を複数プロセス間で共有する事ができます。

=item 分散型Provider

分散化の中ではこれが一番シンプルです。これはただProviderのストレージを
データベースやメッセージキュー等に指定し、そこからデータを出し入れする
だけです。

=back

=head1 Q. "リクエストを取得するのに時間がかかっているようです。どんな対処方法がありますか？"

これは様々な因子が関係していますが、まず以下のような点を注意してみてください：

=head2 あなたのデータセットはGunghoと合ってますか？

Gunghoは非同期エンジンを使用し、POE::Component::Client::Keepaliveでソケット
接続をキャッシュします。

このような動作をするGunghoを使う場合、様々なホストをクロールする分には良い性能
を期待できますが、その逆で例えばひとつのホスト内をクロールするには注意を
しないと思うように性能が上がらない可能性があります。

=head2 Gungho::Engine::POEとloop_delay設定

C<engine.config.loop_delay> は１ループあたりに待つ時間の指定をします。この
１ループ毎にProviderが次に送信するリクエストはあるのか確認し、そのリクエストを
C<send_request()>を通して送信できるかどうかの確認を行います。

もしC<engine.config.loop_delay>が極端に小さい数に設定されている場合、上記
処理を行うためにほとんどの時間を割かれ、実際のHTTP処理を行えない事があります。

逆にこの値が高すぎる場合、Providerにリクエストがあるかどうかの確認をしにいく
までに長い時間がかかり、アイドル時間が増える原因となります。

アプリケーションの詳細な挙動や、データセット内容によって変化する事項なので
この設定項目に対して「正常な値」は存在しません。ただ一般的には５秒くらいの
値から始めて、ログを見つつ調整をしていってください。

=head2 Providerから送られてるリクエスト数を確かめる

Providerは好きなだけのリクエストをエンジンに送る事ができますが、このリクエスト
を調節しないと簡単にマシン／ネットワーク／プログラムの帯域限界を超える可能性が
あります。

継続的にリクエストを送信している場合はある程度スロットリングを施してあげるの
が良いでしょう。

=head2 PoCo::Client::HTTPが詰まる現象を回避する

Gungho::Engine::POEを使用している場合は内部的にPOE::Component::Client::HTTPを
使用してHTTP処理を行います。POE::Component::Client::HTTPは基本的に性能的には
とても優秀なHTTPクライアントなのですが、送信されているリクエスト数が多すぎると
遅くなって行く事があります。

この問題はPOE::Component::Client::HTTPセッションを増やす事である程度対応
できます。C<engine.config.spawn>の数を変更する事により、POE::Component::Client::HTTP
セッションの数を制御する事ができます（デフォルト値は２です）。

ただし、この問題が起こる場合はすでにネットワーク帯域等、他の要因が飽和状態に
なっている可能性が高いのでC<engine.config.spawn>の値を調節するだけでは
特に変化が見られない場合はそちらを疑ってみてください。

=head2 Gungho::Engine::POEとプロキシ

クローラーをプロキシを通して運用するのはよく行われている事ですが、
Gungho::Engine::POEと使用する時にはパフォーマンスが落ちる可能性があるので
注意する必要があります。

プロキシを使用する場合は以下のような設定を指定してください：

  engine:
    module: POE
    config:
      keepalive:
        keep_alive: 0

この設定を行う事によってPOE::Component::Client::HTTPで使用されている
POE::Component::client::Keepaliveを無効化します。Keepaliveは一度接続された
ソケット接続を再利用していくモジュールですが、プロキシに接続している場合は
接続対象サーバーが一つしかないので並列処理が全くできなくなります。なので
この設定を使う事によって、毎回接続を行うようにするというわけです。


=cut
