Scrapboxサーバーが落ちた時の障害分析フロー
絶対にやらない事
metricsを見ずに
いきなり再起動
いきなりdyno数を増やす
これらをやると逆効果な事も多いshokai.icon
サーバーが落ちた時はこの順に原因を考える
Scrapbox外
全世界のインターネット
Slackは使えるか?等
AWS、Herokuなどのプラットフォームの問題
https://status.heroku.com/ を見る
HerokuやMongoDB Atlasなんかは、status pageの更新は人間が行っていて数分〜数時間遅れる
AWSのstatus更新は常に30分ぐらい遅れる
Googleは完全自動かもしれない
サービスステータスはtwitterで検索するのが結局一番速い
どうしょうもないのでService Status Pageやtwitter等で告知して、待つ
問題は全てのdynoで発生しているか、特定のdynoだけか
これ見ると見ないのとで全然違うので、見ましょうshokai.icon
node.jsか、mongodbか、redisか、elasticsearch
一見mongodbが原因に見えても
nodeの何かのエラー → mongodbに高負荷 → 全nodejsサーバー停止、という可能性もある
「DBが詰まった」という結果はよく見られるが、その引き金は別の所にあるかもしれない
逆にNode.jsのメモリ逼迫の原因が、Elasticsearchの性能不足だった事もあった
まずHeroku dashboardのmetricsタブを見る
https://nota.gyazo.com/e649c6e4e84a2970396b23233c45baf5
どんなHeroku Error Codeが出ているか、そして出ていないか
H12 - Request Timeoutが無い
タイムアウトせず、クラッシュしている事がわかる
H10 - App crashed
nodejsプロセスがクラッシュしている
heroku platformのエラーもここに表示される
response timeやmemory usageの欄
この時点で見てもあまり参考にならない
軽く見るだけに留める
logentriesを見る
slack channel #scrapbox-alert
nodejsの実行時エラーならすぐわかる
Heroku dashboardからSSOできる
同じエラーはまとめて1件にしていたりするので、logentries上で見る
エラーが全てのdynoから出ているか、それとも特定のdynoだけなのか
これは絶対に確認するshokai.icon*5
全てのdynoでエラーが出ている場合
DBが原因の可能性が高い
確定ではない。何か別の原因→DB高負荷→全dynoエラー というパターンが有る
Redisかもしれない
addonタブからHeroku Redisのステータスを見に行く
特定のdynoだけがエラーを出している場合
そのdynoのCPUやメモリを使い切るリクエストが来てしまった
json importやexport、ものすごい大きさの編集などが怪しい
Restart all dynosするととりあえず乗り切れる
2020正月明け仕事初めにheap out of memoryでScrapboxがダウンしたの場合も、Logentriesを見たら何が発生していたのか理解できた
インシデントが発生したタイミングでLogentries見れば即時解決できた。反省するshokai.icondaiiz.icon
node.jsとmongoのどちらが原因か確認する
NewRelicを見る
DB待ち時間が長くないか?
mongo
Heroku dashboardからmlabを開き、monitoringタブを見る
グラフの描画範囲を24 hours以上、できれば2 weeksか1 monthに変更する
デフォルトで1時間分しか描画されていない
正常範囲内なのに、直近の分しかグラフを見ていないと見誤る
cache hitしたりしなかったりでスパイクする為
node
難しい
ここまで来てしまうと、もうnodeとmongoどちらが原因なのか確定できない
nodeとnewrelicの組み合わせの不具合でDBに大量のqueryを投げてしまう、等
気合で条件を考えて、切り分けていくしか無いshokai.icon*5
逆に言うと、ここまで来てようやく想像力を働かせるような推論が必要になる
これ以前までは淡々と調査するべき
サーバーが落ちた時、まず推理から入ってはいけない
リクエストの増加
休日→平日
socket.ioの同時接続数
直前にサーバーの根幹に関わるリリースを行っていないか
nodejsの更新など
express、socket.io、newrelicなどのサーバー側のライブラリ
$ git log --oneline