これは地震情報アプリ界隈 Advent Calendar 2021の2日目の記事です。
私が提供している、気象庁の防災情報の再配信APIサービス(個人向け)について記載します。
概要
気象庁から発表された防災情報などのデータは、一般財団法人 気象業務支援センターを通じて民間気象会社や報道各社(ここでは二次配信者という)などに配信されます。
二次配信者又は気象庁HPなどを経由し、ごく普通の人に情報が渡ります。
しかし、まれに生データでもいいから1秒でも早く受け取りたい逝般人がいます。
今回はその酔狂な人が使うサービスが、リアルタイムにデータ配信を行うための工夫などを紹介します。
サービスを作った経緯
二次配信者やその再配信者など、気象庁と受け取りての間が入れば入るほどデータの受け渡しの遅延が大きくなります。
また、気象庁HPでもPULL型として防災情報XMLを配信していますが、データキャッシュなどでどうしても遅延が1分以上発生するので実用性はかなり低くなっていました。
なので、2020年04月より自分でサービス(有料)を作成した次第です。
気象業務支援センターからのデータ受け取り
気象業務支援センターからの情報受け取りはFTP-PUT、自前のFTPサーバーを構築し支援センターから情報が到達後、ファイル名をリネームすることによって送信完了を通知する方法をとっています。
本当にリアルタイム性を追求するならば、同センターが提供している「JMAソケット付きTCP/IP」を使用するべきなのですが接続回線の難易度により現在は断念しているところです。
接続できる回線は、専用線(自分で気象庁本庁まで引く)か、NTT IP-VPN Arcstar Universal One(法人向け)です。
仕方がないのでFTP-PUTを使っています。
しかし、それでも「JMAソケット付きTCP/IP」との遅延は1~2秒遅い程度でしょう。
発信システムの地理冗長受け取り
東京と大阪で同じ内容のデータを1通づつ受け取っています。
どちらか早い/遅いということがままありますが、どちらか早く到達した順に処理を実行していきます。
また、万が一気象庁・支援センター側での障害時にも適切に処理できるようになっています。
実際、2021年01月26日~27日の東日本アデス障害時や2021年03月02日の東日本アデス更新作業による遅延・未配信時にも正常に稼働していました。(一部サイトでは地震情報など更新されなかったところもありました)
サービス構成
現在(2021年12月01日時点)のサービス構成を見ていきましょう。
矢印の色は次の通りです。
黒:FTPやIP/TCPソケットなど
黄:WebSocket
緑:HTTP
紫:MySQL Connection
青:DNS
MySQLと一部を除き地理冗長化、基本同じ処理を並列で行うシステムを構築しています。
なので、どちらか一方が故障してもある程度は情報提供を継続できます。(最近すべての配信が止まったインシデントがありました)
FTPサーバー、IRES、Fileサーバー、WebSocket配信サーバー、APIv2サーバー、認可・認証サーバーはNode.jsで構築しています。
採用した理由ですが私がTypeScriptで開発したかったからと、ライブラリ等が豊富・開発経験がある程度あるからです。(サーバーサードではPHPとNode.jsしかできない)
サービス内で行う防災情報などのデータは、WebSocketによるやり取りを基本としています。
HTTPでもよかったのですが、双方向のデータのやり取り、常時接続によるオーバーヘッドの削減や切断時のリトライ処理など死活監視など併用できることからWebSocketを採用しています。
IRES
受信したデータはすべて「IRES」、情報中継編集システム(いっちょ前な名前)を経由してMySQLへのデータ登録、WebSocket配信サーバーやファイルAPIサーバーへ配信してそこから各利用者へデータが渡っていきます。
また、JSON化など別形式にデータを変換したい場合もIRESに接続して加工したデータを受信生データと同じ経路で配信しています。
このシステムを挟むことによって、データの一元的な編集・均一化とデータ送受信の手間を省くことや、セキュリティー上の対策が強化できるためです。
このシステムの処理時間は1~25ms程度です。
WebSocket配信サーバー
WebSocket配信サーバーでは、接続している利用者へのデータ配信を担当します。
WebSoketで配信行えば、20~100ms程度(通信環境にもよる)でデータを送り込むことができるので、リアルタイム狂にとってもうれしいものとなっています。
そのほか
HTTP APIサーバーなどは電文のリアルタイム性を強化するため、データベースのIndexや構成を適切にし、レスポンス性能を高め、多数のリクエスト(500~1000rps程度)に対しての処理能力に耐えられるように設計・構築をしました。
また、処理時間を短くするため、正常にデータベースや永続化データにデータを投入できなくともWebSocketサーバーに配信する仕組みになっています。
正常に投入できなかったデータはリトライ処理され、復旧すれば自動的に投入するようになっています。
まとめ
最後のほうは投げやりになってしまいましたが、リアルタイム配信・障害耐性を行ううえでの工夫などを一部お見せ致しました。
これにて終わりにしたいと思います。