現在、CakePHPとSOAP通信を用いたAPIを公開しています。
そしてつい先日、「CLOSE_WAITコネクションが残りまくってCPU利用率が100%で張り付いてしまう」と言うログがありました。作業に着手したところ、その調査に約1日・修正に約10分という、膨大な時間の無駄遣いをしてしまったので、備忘録も兼ねて何が起きていたのかを共有しておきたいと思います。
例外の罠
基本的に、処理が成功した場合でも・失敗した場合でも何らかのSOAPレスポンスを返すよう、APIが設計されていました。ただ、いくつかのパターンの場合のみ、例外を投げて強制停止するようになっていました。
タダでさえなんで止まったのかをレスポンスとして返さないだけでも不親切ではあるのですが、強制的にスクリプトを停止させてしまうことが問題の根本的な原因だったのです。
どうやら、PHPとしては例外によって処理をクローズしたと思っていても、通信プロトコルとしては通信が終了していないものと判断し、httpdのプロセスを引き続き稼働させてしまうため、結果としてリソースが圧迫されたということのようなのです。
根本的な対策としてAPIのエンドポイント全体にtry-catchを張り、最終的にどこでも例外がキャッチされなかった場合はシステムエラーのレスポンスを返すよう修正することで、なんとか修正を完了したのでした。
まとめ
検索をしていた過程では英語の情報はばんばん引っかかってきていたのですが、日本語の情報があんまりかかってこなかったため、このバグの供養のためにも今回この記事を書いてみました。皆さんも気をつけましょう。