FessにCPU負荷ベースのリクエスト制御機能を追加

以前の記事でFessにIPベースのリクエスト制限機能を追加したことを紹介しましたが、今回はOpenSearchのCPU使用率に基づいてリクエストを制御する機能を追加しました。OpenSearchの負荷が高い場合にHTTP 429(Too Many Requests)を返すことで、過負荷状態でのサービス品質の低下を防ぎます。

概要

この機能は、OpenSearchクラスタのCPU使用率を定期的に監視し、設定した閾値を超えた場合にリクエストを拒否するサーブレットフィルター(LoadControlFilter)として実装されています。Web画面へのリクエストとAPIリクエストで独立した閾値を設定でき、デフォルトでは無効(閾値100%)になっています。

仕組み

監視の流れ

  1. バックグラウンドの監視タスク(LoadControlMonitorTarget)がOpenSearchのノード統計APIを定期的に呼び出し、各ノードのCPU使用率を取得
  2. 全ノードの中で最大のCPU使用率をSystemHelperに記録
  3. リクエストが来た際に、LoadControlFilterが現在のCPU使用率と閾値を比較
  4. 閾値を超えている場合はリクエストを拒否

制御対象外のリクエスト

以下のリクエストは制御対象外となります。

  • 管理画面(/admin)へのアクセス
  • エラーページ(/error)へのアクセス
  • ログインページ(/login)へのアクセス
  • 静的リソース(CSS、JS、画像、フォントなど)

リクエスト拒否時の動作

  • Web画面: ビジーエラーページにリダイレクトし、「サーバーが現在高負荷です」というメッセージを表示
  • API: ステータスコード429のJSONレスポンスを返却(Retry-After: 60ヘッダー付き)

APIのレスポンス例:

{
  "response": {
    "status": 9,
    "message": "Server is busy. Please retry after 60 seconds.",
    "retry_after": 60
  }
}

設定方法

fess_config.propertiesに以下の設定を追加します。

# Web画面のCPU閾値(%)。CPU使用率がこの値以上のときに429を返す(100: 無効)
web.load.control=100

# APIのCPU閾値(%)。CPU使用率がこの値以上のときに429を返す(100: 無効)
api.load.control=100

# OpenSearch CPU監視の間隔(秒)
load.control.monitor.interval=1

たとえば、APIに対してCPU使用率80%以上でリクエスト制御を有効にする場合は以下のように設定します。

api.load.control=80

Web画面とAPIで異なる閾値を設定することもできます。

web.load.control=90
api.load.control=70

IPベースの制限との違い

以前追加したIPベースのリクエスト制限とは異なるアプローチの機能です。

項目IPベースの制限CPU負荷ベースの制御
制限の基準特定IPからのリクエスト数OpenSearchのCPU使用率
目的特定クライアントの過剰アクセス防止サーバー全体の過負荷防止
設定レート制限、ブラックリスト/ホワイトリストCPU閾値(Web/API独立)

両方の機能を組み合わせることで、より効果的にサーバーを保護できます。

まとめ

CPU負荷ベースのリクエスト制御機能により、OpenSearchが高負荷状態のときにFessが自動的にリクエストを制限できるようになりました。デフォルトでは無効になっているため、必要に応じて閾値を設定してください。

Claude Codeをバージョン指定でインストールする

この前、Claude Code 2.1.27でフリーズして使えなくなる問題が発生しました。このような場合、過去のバージョンを指定してインストールすることで回避できます。

バージョン指定でインストール

Claude Codeは通常のインストールスクリプトにバージョン引数を渡すことで、特定のバージョンをインストールできます。

curl -fsSL https://claude.ai/install.sh | sh -s -- 2.1.25

これで~/.local/bin/claudeにコマンドがインストールされます。

自動更新を無効化して実行

Claude Codeは実行中に自動更新が行われるため、せっかくバージョン指定でインストールしても更新されてしまいます。自動更新を無効化するには、環境変数DISABLE_AUTOUPDATERを設定して実行します。

DISABLE_AUTOUPDATER=1 ~/.local/bin/claude

毎回入力するのが面倒な場合は、エイリアスを設定しておくと便利です。

alias claude='DISABLE_AUTOUPDATER=1 ~/.local/bin/claude'

アンインストール

Claude Codeをアンインストールする場合は、以下のファイルとディレクトリを削除します。

rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude

まとめ

新しいバージョンで問題が発生した場合は、この方法で過去のバージョンに戻すことで一時的に回避できます。問題が修正されたら、通常通りインストールし直して最新版に更新しましょう。

AIドリブン開発のためのfess-workspaceリポジトリ

Fessの関連リポジトリは30個を超える感じになっており、Claude Codeとか使って、個々のリポジトリでの改修も限界がありました。たとえば、FessのWebアプリ側を修正しながら、クローラーのコードも修正するような場合は、リポジトリを横断して、対応する必要があったりと。

関連するリポジトリを横断的に修正ができるようにするために、fess-workspaceを作りました。今のところ、いい感じに使えています。たとえば、Fess 15.5からJUnit 5に移行しましたが、30個くらいあるリポジトリも同様に移行する必要があるのですが、Fess本体を参考にして、各リポジトリをClaude Codeに修正依頼したら、JUnit 5移行もさくっと完了しました。

という感じで、今まで、横断的な修正が面倒だなーと思っていたものはfess-workspaceで修正していこうかなと考えています。