21時44分08秒 [Web関連]
私が運営しているとあるウェブサイト(※このブログがあるサイトではありません)では、ある外部WebサービスのAPIを利用してページを生成しています。
そのWebサービスのAPIには1日あたりのリクエスト数に制限があるため、それを超えてリクエストを送るとエラーが返ってくるようになってしまいます。なので、リクエスト数を超えないように利用頻度の調整が必要です。
元々そんなに多くのアクセスがあるとは想定していなかったサイトなのですけども、調べてみると1日あたりのAPIリクエスト数が結構高いところまで増えてしまっていました。23時29分の時点で権利数の95%を消費していて、ちょっとでもアクセスが集中することがあったら権利を使い果たしてしまいそうな感じです。
以下は、そのウェブサイトを構築したときに、クローラーからのアクセスだけでAPI利用権を使い尽くしてしまわないようにするために採った施策の話です。
サーバのアクセスログを見てみると、本当にユーザ数が多いわけではなく、大半はbot(クローラー)からのアクセスでした。元々いくつかの方法でbotからのアクセスを弾いたり頻度を制限したりする施策は加えてあったのですが、お手製のフィルタをすり抜ける新しいbotが現れることもあります。放っておくと、1日に数千回のような莫大な回数もアクセスしてくる悪質なbotが時々現れるので困ります。(-_-)
Webサイトへのアクセスをそのまま(Webサービスの)APIに投げるようなことはしておらず、同じデータは一定期間(数週間)は再取得せずに済むようにキャッシュを取ってはいるのですけども、それでもbotの数が増えてアクセス頻度も増えれば、いつかは1日のリクエスト数の上限に達してしまうわけで、何らかの対策は必要です。
今は「botのようだったらフィルタを通す」というようなプログラムを書いているのですが、これだといたちごっこになりがちなので、どうしても対処できなさそうなら「人間っぽくなければ全部フィルタを通す」というような方法にせざるを得ないかもしれません。
前者の方法を採用しているのは「マイナーなアクセス環境から来ている人にも正しく閲覧できるようにしたい」と考えてのことです。後者の方法を採ると「本当は人間なのに弾かれてしまう」ケースが出てくる可能性があるので、できるだけ最後の手段にしたいとは思っているのですが……。
で、サーバのアクセスログを詳しく確認してみたところ、なんとMicrosoftの検索サイト「Bing」から来るクローラーであるBingbotも結構な頻度でアクセスしてきていたことに気付きました。
Bingbotのアクセスは1日で10,785回でした。1日(24時間)は秒に換算すると86,400秒ですから、12秒に1回くらいのペースですね。
なんでそんなに……。(^_^;;;
というわけで、まずはBingbotのアクセス頻度を下げる方法を試しました。
Microsoftが提供しているBing Webmaster Toolには、クロール時間帯を調整する機能はあるのですけども、クロール総数(頻度)を抑制する機能はなさそうです。
しかし、robots.txtに「Crawl-delay」の項目を加えて値を書いておくことで、クロール間隔の指定は可能なようでした。
検索サイトのクローラーへの指示方法として代表的なのはrobots.txtファイルを設置しておくことですね。
Bingbotが1日にrobots.txtを何回読んでいるのかなと思ってログを調べたら、70回も読んでいて驚きました。robots.txt以外の全ページを含めたアクセス回数が10,785回でしたから、Bingbotは全クロールの0.65%をrobots.txtの読み込みに使っていることになります。アクセスログを見たのは1日だけなので、毎日そうなのかどうかは分かりませんけども。(ちなみに、Googlebotがrobots.txtを読む頻度はだいたい0.1%くらいでした。)
とりあえずrobots.txtに、以下の2行を加えてみました。
User-agent: Bingbot Crawl-delay: 30
翌日に確認したところ、6割減くらいにまで削減できていました。(Bingbotが凄まじく大量にアクセスしまくっていたことにも驚きましたが)robots.txtに制限(Crawl-delay)を書くだけであっという間に制限に従ってアクセス頻度を低下してくれたことにも驚きました。
さすがにMicrosoftの名前を冠してアクセスしてくるだけあって、(デフォルトの行儀はともかく)明示的な制限にはきっちり従ってくれるようですね。
GoogleのクローラーであるGooglebotは、当初はかなーり上品な頻度(要するに少ない頻度)でしか来なかったのですけども、(日々増えるページが自動追加される仕組みの、動的に生成した)サイトマップXMLを少し前にGoogle Search Consoleへ登録しておいたところ、予想以上にアクセス頻度が高くなり、結構な頻度でアクセスされるようになりました。アクセス自体はありがたいのですけども、これもまたAPIの利用権を半日で使い果たしてしまうくらいの高頻度だったので、ちょっと制限が必要になりました。(サイトマップXMLって、ちゃんと読まれていて、しっかり効果があるのだなと実感しました。^^;)
Googlebotは、robots.txt内に「Crawl-delay」を書いても読まない(解釈しない)仕様のようです。Googlebotのクロール頻度を下げる方法は、Googleによる解説ページ「Googlebot のクロール頻度の変更」に書かれています。ただ、ここに書かれていることは基本的に「Googlebotのクロール頻度をWebサイトオーナー側が指定することはできない」ということですが。^^;
Google側は一応はクロール頻度(最大頻度)を指定できる設定ページを用意しているのですけども、90日間しか有効ではなく、90日後には自動判断に戻ってしまう仕様です。何より、今回クロール頻度を調整したいのは、「外部WebサービスのAPIリクエスト権に上限があること」が原因なので、「APIを利用せずに出力できるページのアクセスを制限する必要はない」という点があるので、クロール頻度(の上限)そのものを指定する方法はあまり適切ではありません。
Googleの解説にはもう1つ「緊急クロールの制限」として、「負荷の増大を動的に検出して対応できるなら『HTTP 429』を返せ」と書かれています。そうすると、そのうちGooglebot側が学習してアクセス頻度を落とす感じなようです。今回はその方法を採用しました。具体的には、API利用権の残数が少なくなってきたときに、「APIを利用しないと出力できないページ」にアクセスされた場合にだけ、HTTPステータスコード429(Too Many Requests)を返すようにPHPを書きました。
当初は検索サイト以外から来るbotでも、アクセスを問答無用で拒否したりはせず、ある程度だけ制限した上で許可するような方針で運営していたのですけども、上述のように検索サイトからも結構な頻度で来てくれるので、有名検索サイトからのクローラーだけを優遇する方針に変えました。
具体的には、Googlebot、Bingbot、Applebotだけを特別扱いして、それ以外のBotは概ねブロック(完全にブロックするわけではなくて、外部サービスのAPIを利用して生成しなければならないページだけでブロック)する方針にしました。
一度でも人間または有名検索サイトのクローラーがクロールすれば、一定期間はサーバ側でキャッシュされる仕組みを作ってありますから、その静的キャッシュページにはそれ以外のBotでも何でも大量アクセスされて問題ありませんので、そういうページへのアクセスは何もブロックしません。なので、この制限の仕組みを施しているからといって、必ずしもBotへ情報が遮断されるわけではありませんから、この方針でも概ね問題なさそうだと思っています。
当初はそんな行き当たりばったりの感じで対策を施していたのですけども、それでも全体のページ数が増えれば増えるほど、クローラーのアクセスも増えるかも知れませんし、ずっとこの方法でいくのは無理があるな、と思いました。
そこで、最終的には「1日のAPIリクエスト数がXXXX回を超えたら50%ブロック(=HTTPステータスコード429を返す)し、YYYY回を超えたら75%ブロックし、ZZZZ回を超えたら100%ブロックする」というように、具体的なリクエスト総数に応じて多段階にブレーキを掛ける仕様を加えました。
よく考えれば最初からこう作っておけば良かったのですけども。
この方法なら、API利用権を使い切ってしまうこともなく、余らせすぎることもなく、良い感じに自動運営ができそうな気がします。やや心配なのは、HTTPステータスコード429を返す期間が長すぎるとGoogle側が学習してアクセス頻度を大きく低下させてしまう可能性があるかもしれない点なのですけども。(極端な話、「午前中(AM)はアクセス可能で、午後(PM)は完全ブロック」のようになりかねないので、1日の後半のHTTP429数の多さだけから学習されてしまうと困ります。Google側も24時間単位で考えてくれるなら良いのですが。)
しかし、上記の方針で数ヶ月ほど運営してみて、ほぼ毎日同じくらいの分量の「ほどほどのクロール」が続いているようですから、わりと良い対処方法だったのかなと評価しています。
この日記へのコメントはお気軽に! コメント数:0件
(前の記事) « IO DATA製31.5インチ液晶ディスプレイ EX-LDQ322DBを買ったので設置
前後のエントリ
< 旧 / 新 >
(次の記事) PCデスクを新調するなら背面や側面は金属製がお勧め »
コメント数: 0件