この記事は 防災アプリ開発 Advent Calendar 2024 3日目の記事です。
昨日は 黒板ちゃん(さん)の記事 でした。
はじめに
昨年12月から「EarthQuickly for Discord」というDiscordボットを公開しています。
昨年のアドカレでも、Discordの地震ボット作りましたよ的な記事を書きました。
今回は、そのボットを1年間運用してみて得られた知見を書きたいと思います。
【1月1日】本番は突然に
年が明けて間もない 1月1日16時06分、石川県能登地方で最大震度5強の地震が発生。
この地震で緊急地震速報(警報)が発表されましたが、
これがEarthQuicklyボットにおける最初の警報でした。
元日からでかい地震はやめてくれよ...
と思った矢先でした。
1月1日 16時10分
令和6年能登半島地震が発生しました。
最大震度7。そんな地震がまさかこのタイミングで来るとは。
本震発生時のEarthQuicklyボットの導入数は50サーバー程度。
とはいえ、連続で発表されるEEWや地震情報は負荷が高いものでした。
そして、決して喜ばしいこととは言えませんが、
地震発生と同時にEarthQuicklyボットの導入数が急増し、
17時頃には未認証状態での最大値である100サーバーに到達しました。
顕著に表れる最適化不足
1月1日は本震や連続する余震の影響で、1日中動作が不安定でした。
特に、地震発生から1時間以内に複数回クラッシュしたログが残っていました。
詳細に検討したところ、以下のシナリオだと分かりました。
・EEW予報の処理で、キャンセル報の処理が上手く行かずクラッシュ。
・クラッシュを検知し、自動再起動が働く。
・サーバーが重くなっていた中、ボットを再起動する時の処理が重すぎてクラッシュ。
・また再起動を試みても、再起動の処理が重すぎてクラッシュ。
・これを繰り返す。
強制的にサーバーごと再起動することで一旦解決はしましたが、
根本的に処理を改善するまでは、何度もこの問題に苦しめられました。
クラッシュを検知し、自動再起動が働いたらWebhook経由で通知が来るようにしています。
上手く行った点
クラッシュは多発しましたが、ダメな所ばかりではありませんでした。
それは震度7の地震情報や大津波警報という非常に重要なお知らせも、
予定通りに送信できることが証明できたことです。
当時、この津波情報が送信されたのは推定で60チャンネルほどですが、
少しでもEarthQuicklyボットのおかげで危険を回避できた人がいればいいな。と思います。
【4月3日】突然の津波警報
ボットの導入数は700鯖程度に拡大していた中、台湾でM7.2の地震が発生。
緊急地震速報(警報)と津波警報が発表される事態となりましたが、
EarthQuicklyボットでは正常に配信を完了することができました。
【4月17日】VPSの限界
緊急地震速報(警報)が発表され、
EarthQuicklyボットは予定通りに送信を完了したと思われました。
しかし、いつまで経っても震度速報が送信されません。
その後緊急地震速報(予報)は送られてきましたが、明らかに遅延しています。
その後ボットは、震度速報を送信中にクラッシュ。
かなり重大な問題でしたので、すぐに原因究明を開始しました。
無駄に使われた帯域
普段、Discordで画像を添付して送信するとき、画像の送信に少し時間がかかると思います。
これと同じ現象がこの時のEarthQuicklyボットに起きていました。
Discordボットから画像を添付してメッセージを送信するとき、
添付の仕方は次の2つがあります。
・画像データを直接メッセージに添付する(内部生成した画像を使える)
・画像が置いてあるURLを添付する(ネット上の画像を使う)
当時のEarthQuicklyボットでは、前者の方法を使って送信していました。
地震情報の画像を内部で生成して送信するため、通常ならこの方法を用いるからです。
しかし、当時のEarthQuicklyボットは既に800鯖以上に導入されていました。
仮に1サーバーにつき1チャンネル送信していたとすると、
一つの情報で800回以上画像を送信する必要があります。
また、緊急地震速報(予報)が数秒ごとに更新されることも踏まえると、
いかに短時間で大量の画像を送信しているかが分かると思います。
結果的にVPSの 100Mbps という帯域ではこの大量の画像送信に耐えることができず、
徐々に情報送信が遅延していった、というわけです。
急いで再起動した結果、「各地の震度に関する情報」はなんとか送信できました。
改善方法
これを改善する手段は一つしかありません。それは、
画像が置いてあるURLを添付する ことです。
地震情報が発表された際には、内部で生成した画像をnginxのフォルダに保存しておきます。
ボットからは、それに対応したURLを添付しておきます。
そうすると、ユーザーがボットのメッセージを見たタイミングで
Discord側から画像を保存してあるURLへリクエストを飛ばし、画像を持ってきてくれます。
またCloudflareを間に挟むことで、CF側でうまいことキャッシュしてくれます。
これによりサーバーに極端に負荷をかけることなく、
画像を含んだメッセージを送信することが可能になりました。
【6月3日】効いた対策、現れた盲点
月曜日の朝から緊急速報メールに起こされた中、
幸いにもEarthQuicklyボットは予定通りに動作してくれました。
緊急地震速報(警報)や地震情報もうまく送信完了することができました。
10分後
6時40分、再び地震が発生し緊急地震速報(警報)が発表されました。
しかし、いつになってもEarthQuicklyボットから警報が送信されてきません。
仮定震源要素なEEWが出た時の処理に一部ミスがあり、
結果的にそれが原因でクラッシュしてしまいました。
※現在は修正済みです。
【8月8日】Discordボット開発の"魔物"
8月8日16時43分、日向灘でM7.2の地震が発生しました。
南海トラフ地震臨時情報が発表されるほどの地震となりましたが、、、
EarthQuicklyボットの挙動は、とてもじゃないですが「酷い」の一言でした。
およそ1700鯖程度に導入されていたこのボット。
ついに「レートリミット」に直面することになります。
効かなかった対策
EarthQuicklyから送信される情報の大半を占めるのが、「緊急地震速報(予報)」です。
EEW予報が、将来的にレートリミットの原因になるだろうなと予測していたため、
推定最大震度が変化したとき のみ送信するような処理をしていました。
実際、この地震より前にレートリミットが問題となったことはなかったため、
この対策はある程度効いていました。
しかしこの地震では、
急激に増加する導入数 と 能登半島地震に次ぐレベルの大きな地震 が重なった結果、
ついにこの対策では歯が立たなくなり、レートリミットに引っかかってしまいました。
そして、レートリミットに数分間引っかかり続けた結果、Cloudflareからの制限を受け、
約1時間ボットが一切動作しなくなる事態になりました。
ボットの再起動しようとしても、そもそもログインの時点で弾かれてしまいます。
そのため、この地震で発表された津波注意報やその後の余震に関する情報を、
約1時間一切送信することができませんでした。
これは地震情報を送信するボットとして、起こしてはならない事だと思います。
2度とこのような事態を起こさないように、数日かけて対策を練りました。
【11月26日】実証できた対策
ボットの導入数は約2700鯖まで伸びた中で、久しぶりの緊急地震速報(警報)でした。
しかし、ボットは最後まで止まることなく動作を続けてくれました。
確実にあの時の反省と対策が生かされています。
最後に
ここまで、2024年のEarthQuickly for Discordの運用記録を書きました。
紆余曲折ありましたが、約2900鯖に導入されるまでに成長しました。
今後もより安定した情報発信ができるようにしていきたいと思います。
最後までお読みいただき、ありがとうございました。