図書館クロール補足

なんか技術的におかしなことを言っている人がいたら追記していくかも知れません。

クロール頻度が妥当かどうかの話

ウェブサーバーはマルチスレッド、マルチプロセスなどで複数のリクエストを同時に処理できるようになっているのが一般的であるため「前回のリクエストが完了してから、次のリクエストを投げる」実装になっている限りは「サーバーの性能を100%使いきって他の利用者が利用できない状態」になることは、通常起きません。

例外的なケースもあります。

  • ウェブサーバーがリクエスト完了後に何らかの処理を行うような実装になっていて、リクエストのペースによっては処理が溜まっていって追いつかなくなる。
  • ロードバランサ、リバースプロキシを使ったフロントエンド/バックエンドの構成になっているサーバーで、フロントエンドがタイムアウトと判断して早々にエラーを返したが実際はバックエンドで処理が続いている。

例えば1秒で処理が終わらないページ(例:LIKE検索)に対して、レスポンスの受信を待たずに1秒に1回のペースでリクエストを投げ続けたら、サービス停止を引き起こせるでしょう。ですが、並列してリクエストを投げていないのに「お前のリクエストが原因で他の利用者が利用できない状態になった」という主旨のことを言われたのであれば、それは通常言いがかりです。他の利用者のリクエストと合わせて過負荷状態になっている(一人の責任にされるべきものではない)か、アプリケーションのバグが原因の事故であると考えるのが自然です。

「サーバーリソースが限られているので遠慮してくれ」というのは、別段おかしなことではありません。が、サービス停止の責任を追求されるのは異常なことです。

1秒1回のペースが妥当かどうかとか、どの程度のウェイトを入れるべきなのかという話は、クロール対象のサービスの規模や、静的ページか動的ページかなどによっても変わるでしょう。もし書いたプログラムを配布する場合は、複数の利用者によってリクエストが同時に投げられることになるので、慎重さが要求されるでしょう。

開発中で自分の手元でしか動いていない相手先のサーバーに並列アクセスしないクローラが原因でサービスが落ちて他の利用者が迷惑しているといって責任を追求されるというのは、技術的におかしいことを言われているのです。それは予見できない事故です。並列アクセスしてないのにサーバーが落ちるのであれば、それはサーバー側のバグが原因である可能性が高い(実際そういう考察をしている人が何人かいますね)。

という程度のことを警察が判断できるようになると良いですね。

適切なエラーハンドリングについて

http://librahack.jp/okazaki-library-case/conclusion.html

相手サーバからのレスポンスHTTP500を細かくハンドリングせず単にスキップだけしていた

これ特におかしなことではないです。おかしいと思っている人は、今回のケースでエラー処理を怠ることによって相手先のサーバーに何か損害を与えうると考えていますか?むしろ不適切なエラー処理(際限なくリトライなど)をしたほうが損害を与える可能性が高いです。

一部の特に行儀の良いクローラであれば500エラーが返ってきた際に同一のサーバーに対するクロール頻度を下げるなどするでしょう。一度エラーが起きたURLに対してリクエスト内容を修正せずに、間を置かずにリクエストを繰り返すのは、同様のエラーが返ってくる可能性が高いので避けるべきです。しかしスキップして次のURLを取得するのであれば、別のリクエストですから正常に返ってくる可能性があります。

連続して500エラーを返していた場合でも、それが自分のリクエストによってサービスダウンを招いているという(並列アクセスを捌けるサーバーに並列アクセスしてないのに自分のリクエストだけが原因でサービスダウンが引き起こされることは無いだろうという技術者としての常識を覆しての)推測は通常されるものではありません。ましてや500エラーから図書館業務が妨害されたことを推測してクロールを中止せよというのは無茶苦茶なことを求めています。

ちなみに503エラーであればサーバーが過負荷かメンテナンスです。時間をおかずに次のURLにアクセスしても503の可能性が高いです。サーバーの負荷が高いためウェイトを入れてくれというのは、Retry-AfterというマイナーなHTTPヘッダを使うことで実現できます。ただしRetry-Afterを出力するサービスも考慮するクローラも、ぶっちゃけあまり無いと思います。Google Code Searchで検索したところいくつか実装例が出てきましたが、数少ないです。
http://www.studyinghttp.net/status_code#Code503

逆に問題があるエラーハンドリングは以下のようなものでしょう(サーバーが落ちても良いと思っていると判断されかねないもの)

  • エラーが解消されるまで(適切なウェイトや最大試行回数を考慮せずに)リトライする
  • 負荷が原因でアクセス制限を受けているということを知った上で、アクセス制限を回避するための工夫をする。

正しい技術的知見の適切な啓蒙について

ソフトウェアのバグ、脆弱性、不具合であれば、それが直ったかどうかが明確に判別が出来るだろうし、時にはそのようなバグは恥ずかしいと非難を浴びせることもあるでしょう(それが技術レベルの向上に繋がることもあります)。しかし「クローラにどの程度の安全機構を組み込むのか」という問題になると、人によって感覚が異なるようです。事故を起こさないためにどの程度の対策をしておけばいいのかというのは、個々の経験則に依る部分が大きいのでしょう。(ここで交通事故に例えるのは不適切です)

私が主張したいのは以下のようなことです(クローラに限った話ではなく一般論として)

  • お前らは人が趣味で数時間で作った程度のものに一体どの程度のレベルを要求しているのか、身の程を知れ。
  • 実態を知らない初心者(もしくは老害)が「これぐらいのことやって当然だよね」などと平然と口にする、何様のつもりだ。
  • 普段はまるで問題にしていないようなことを事故が起きたときに限って「過失があった」といって騒ぎ立てるなクズども。

世の中で稼働しているソフトウェアはバグだらけです、例えばオープンソースプロダクトのChangesを読めばわかるでしょう。仕様やプロトコルを守っているソフトウェアばかりではないし、それでも世の中は動くように出来ているのです。全くお前らは人のミスを責めたてることにばかり夢中で全く生産的ではないばかりか、時に全く問題のないことに対してまで、過失があった、不注意であったと、騒ぎ立てて間違いを広める。そのような行為は啓蒙ではないし、害悪だ。

良いクローラの条件

自分が考える良いクローラの条件は、事故起こさない方法を追求しても限度があるので「何か問題が起きた場合にアクセス拒否する方法が分かりやすい」ことです。アクセス拒否したときに他のユーザーが巻き添えを食わないことなども含みます(動的IPやブラウザに偽装してたりすると面倒)。今回の事件に関して言えば、最初に稼働させたのが固定IPのレンタルサーバーなので、まあ問題ないでしょう。そもそも図書館側がアクセス拒否する方法を知らなかった可能性がある。

という程度のことを警察が判断できるようになると良いですね。