ENECHANGE所属のエンジニア id:tetsushi_fukabori こと深堀です。
実は今年の4月に育児休業から復職していました。
このブログの主旨からは外れるので特段書きませんが、育休は最高の体験でした。機会があればお勧めします。
今回から何回か使って弊社アプリケーションで発生したエラー事象とその調査について記事を書きます。
エラーが発生したアプリケーションはいわゆるwebアプリケーションなのですが、原因の調査手法としてはパケットキャプチャを行うことになりました。
普段webアプリケーションの開発ではあまり出番が無い(と思う)パケットキャプチャなので、方法などを共有できればと思います。
今回はエラー事象の概要から調査戦略の決定までの説明です。
序章的な立ち位置なのでさほど技術的な文章ではないです。
技術的な話は次回以降をご参照ください。
この記事を届けたい人
- AWSで構築したアプリケーションでパケットキャプチャをやりたい人
- キャプチャしたパケットを解析した事例を知りたい人
エラーが発生したアプリケーションの構成
今回エラーが発生したアプリケーションのシンプルな構成は以下のとおりです。
アプリケーションはユーザーのリクエストを受けて内部処理と外部API呼び出しを行って結果を返します。
内部処理または外部API呼び出しでエラーが発生するとユーザーにエラーレスポンスが返ります。
アプリケーションはRuby on Rails製で外部API呼び出しに際してはFaraday gemを利用しています。
また、エラーの検知にはbugsnagを利用しており、エラー発生時にはstacktraceや例外オブジェクトの情報をブラウザで確認可能です。
発生したエラー
発生したエラーは弊社アプリケーションサーバーから外部API呼び出し時のFaraday::ConnectionFailed
エラーです。
StandardError#message
の結果は以下のいずれかでした。
execution expired
(エラーパターン1)Connection reset by peer
(エラーパターン2)
呼び出しから60秒(エラーパターン1)または30秒(エラーパターン2)に上記エラーが発生しており、発生の頻度やタイミングはまちまちでした。
また、AWSのインフラ上はエラーを検知しておらず、AWSのサービスとしてはNWインフラの障害などではなくあくまでアプリケーションの不具合でした。
このエラーはAPI通信時に必ず発生するわけではなく、API通信のうちの一部でのみ発生しています。
エラーとなるリクエストの内容からは特段傾向は見られませんでした。
エラーの考察
この時点でエラーについてわかっていることを列挙します。
- Faradayがエラーを出力していることからAPI通信処理中のエラーである
- アプリケーションにユーザーからリクエストが到達してからほぼ一定時間経過後にエラーとなる
- パターン2ではコネクションのリセットが行われている
素朴に推測すると「API通信中に何らかの問題が発生しタイムアウト時間に到達しコネクションの切断がされている」と読めそうです。(読みました)
おそらくパターン1とパターン2では切断のトリガーとなるタイムアウト時間の設定が別々のものが適用されていることでタイムアウト時間が異なるかもしれません。
また、TCPヘッダにはコントロールビットという制御フラグ用の領域があり、そのうちRST
(Reset)ビットはTCPコネクションの切断を求めるビットです。
(参考:TCPのRFCの該当箇所)
Connection reset by peer
というエラーメッセージからパターン2はRST
フラグが設定されたパケットを受信したことで発生しているかもしれません。
エラー原因調査方針
通信中のエラーであり、特定のTCPパケットを受信していることが推測されるため、パケットの粒度で通信内容を解析することが必要と考えました。
当初はAWSインフラ内での通信を確認するためVPCフローログで調査を行うことも検討しましたが、パケット単位で通信を確認したかったため見送りました。
ユーザーからのリクエスト到着後からAPIリクエスト開始までに時間がかかっていないか、正常時とエラー時を比べてやり取りしているデータは何が異なるのか…などなど、知りたい情報の粒度に対してはパケット解析が妥当と考えました。
このため今回はVPC Traffic Mirroringを使って調査をおこないます。
エラー原因調査の基盤構成概要
VPC Traffic Mirroringはその名の通りVPC内のトラフィックをミラーリングできます。
この機能を使い本番EC2インスタンスに出入りするすべてのトラフィックをパケットキャプチャ用のEC2インスタンス(新設)にミラーリングし、パケットキャプチャ用EC2インスタンス上でパケットキャプチャとパケット解析を行う方針にすることで以下のようなメリットがあります。
- アプリチームが運用する本番EC2インスタンスに手を加えずにパケットキャプチャができるためインフラチーム単独で環境を作りやすい
- 本番EC2インスタンスのリソースを消費しないのでアプリ影響がない
- 本番NW内で解析まで完結するのでセキュリティを担保しやすい
構成は以下のとおりです。
次回は上記構成の構築と運用について記事にします。