瑞鳳でMyFleetGirlsが落ちた話
起こったこと
21日の深夜にMyFleetGirlsが接続不能になった。この時点でCPUが100%に張り付き一瞬でT2インスタンスのCPUクレジットを消尽した。
22日の昼に片手間で復旧作業を開始。最初EC2インスタンスの不都合かと思って雑に再起動をかけるが直らず100%に張り付く。このあたりで採掘を疑う(完全に見当違い)。すぐに復旧できなそうなので放置。
仕事中に無限ループの可能性に思い当たり、夜にログを見て調査してみると、起動時のRanking処理で落ちていることが分かる。
→コードを読み返していくとEvolutionBaseという改造元検索アルゴリズムに不都合に思い至る。
→21日の深夜に瑞鳳改二増えてるで
→瑞鳳がわるい!
原因
MyFleetGirlsは艦これとの通信をproxyすることで通信を覗いて、必要なデータをサーバに送る仕組みで、このときMyFleetGirlsの動作に必要なマスターデータも必要に応じてupdateしてもらう。
瑞鳳改二の実装により艦娘のマスターデータが更新されたので、一番最初に接続したユーザから自動でマスターデータを受け取っている。
そのうちの1つに艦娘改造先マスターデータがある。
id | aftershipid | afterlv | name |
---|---|---|---|
116 | 117 | 25 | 瑞鳳 |
117 | 555 | 80 | 瑞鳳改 |
555 | 560 | 80 | 瑞鳳改二 |
560 | 555 | 80 | 瑞鳳改二乙 |
nameは分かりやすくするために付けたがこんな感じである。
で、MyFleetGirlsには改造元を知りたいときが割とあって、艦娘毎の人気とかを知るための集計類は改だろうが同じ娘なので集約してーとかやったりする。なので改造元を計算するEvolutionBaseというclassを置いている。
ここで厄介なのが改二と改二乙で、改造元が循環してしまう問題がある。実際に循環したことがある。なので、進化元を辿るときはidの小さい方を優先するようにしている。(これは今思うと不十分である。後で述べる対応策で解決している)
上の正しいデータが来ていればMyFleetGirlsが落ちてこのblogを書くこともなかったわけだが、一番最初のユーザがマスターに上げてきたデータは以下のようなものである。
id | aftershipid | afterlv | name |
---|---|---|---|
116 | 117 | 25 | 瑞鳳 |
117 | 0 | 80 | 瑞鳳改 |
555 | 560 | 80 | 瑞鳳改二 |
560 | 555 | 80 | 瑞鳳改二乙 |
あとはわかるな?AWSの虎の子インスタンスは永遠に瑞鳳改二と瑞鳳改二乙の間を行き来することだけに全てを費やし始めたのだ。
なんというかありそうなミスではあるが、MyFleetGirlsを殺すには十分な破壊力があった。
教訓
- CPU使用率が張り付いたら無限ループを疑え
- 再帰は必ず回数をカウントしろ
- 自分の管理外のサーバが正しい情報を返してくる前提で事を進めるな
対応策
復旧はデータの修正と再起動だけで片を付けたが、そのあとで再帰カウントを導入した。