プロジェクト環境
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
Dockerコンテナ環境で運用
問題の概要
アプリケーション内で非同期マルチスレッド処理が広く使用されています。各非同期タスク内ではデータベースクエリ、Redis参照、Feign呼び出し、RabbitMQの送受信が複雑に絡み合っています。シングルサーバー構成のため、短時間でTomcatがハング状態に陥りました。サービスは継続的に稼働していますが、すべてのHTTPリクエストが不通となり、ヘルスチェックページすら開けない状況が発生しました。コンテナ自体は正常に動作しています。
発生エラー
ネットワークリクエストすべてで以下の例外が発生しています:
feign.RetryableException: Read timed out executing POST
スタックトレースからSocketTimeoutExceptionが確認できます。Feignクライアントがターゲットサービスからの応答を長時間待機状態となっています。
調査ステップ
1. コンテナへのアクセス
docker exec -it コンテナID /bin/bash
2. ネットワークツールのインストール
apt-get update
apt-get install net-tools
3. TCP接続状態の調査
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
アプリケーションが停止していないにもかかわらず、接続数が増え続けている場合、接続の詰まりが発生している可能性があります。
4. プロセス確認
top
Javaプロセスの状態を確認します。
5. スレッドダンプの取得
# プロセスIDの確認
ps -ef | grep java
# スレッド情報の取得
jstack プロセスID
# ファイルに出力
jstack プロセスID > thread_dump.txt
6. ホスト側へのファイル転送
docker cp コンテナID:/path/to/thread_dump.txt ./
スレッド状態の分析
ダンプファイルを分析した結果、多数のCompletableFuture$Signaller.block状態スレッドが確認されました。以下はスレッド状態の解説です:
| 状態 | 説明 |
|---|---|
| NEW | 未起動のスレッド。ダンプには表示されない。 |
| RUNNABLE | VM内で実行中の状態。locksを獲得している場合あり。 |
| BLOCKED | モニターロックを待ってブロックされている状態。 |
| WAITING | 無期限に他のスレッドの操作を待機。park()、wait()、sleep()、join()などで停止。 |
| TIMED_WATING | 時間制限付きの待機。wait(timeout)など。 |
| TERMINATED | 終了したスレッド。 |
根本原因の特定
分析の結果、非同期処理で結果を取得する際にデッドロック
解決方法
非同期処理にタイムアウト設定を適用しました。具体的には、10秒間のタイムアウトを設定することで、無限待機を防止しました。
// 修正前のコード(問題あり)
CompletableFuture<Result> future = CompletableFuture.supplyAsync(() -> {
return remoteService.call();
});
Result result = future.get(); // 無限待機
// 修正後のコード
CompletableFuture<Result> future = CompletableFuture.supplyAsync(() -> {
return remoteService.call();
});
try {
Result result = future.get(10, TimeUnit.SECONDS);
} catch (TimeoutException e) {
// タイムアウト時の処理
future.cancel(true);
log.error("非同期処理がタイムアウトしました");
}
追加の改善ポイント
リソースプールの確認も重要です。以下のリソースが適切に設定されているか確認してください:
- データベース接続池(HikariCPなど)
- Redis接続池
- スレッド池(ThreadPoolExecutor)
- Feignクライアントのタイムアウト設定
参考資料
同様の問題遭遇時の参考URL:
- https://blog.csdn.net/zcjluse/article/details/125974518
- https://www.cnblogs.com/fengyege/p/16936291.html