SPIRAL®の「30秒の壁」を突破せよ!
外部サーバ連携による大量データ処理の最適化

- SPIRAL
「SaaSは便利だけど、自由度が低くてかゆいところに手が届かない......」
そんな経験はありませんか? 今回のプロジェクトでは、自治体向けのWeb申請システムを構築するにあたり、堅牢なPaaS基盤である「SPIRAL®」を採用しました。
しかし、ここでSPIRAL®技術者なら一度はぶち当たる「30秒の壁(タイムアウト制限)」という大きな課題に直面しました。
■【課題】数万件のCSV処理にSPIRAL®単体では限界が......
自治体案件ともなると、扱うデータは数十万件規模におよびます。
- ・大量の申請データをCSV形式で一括ダウンロードしたい
- ・逆に、CSVを読み込ませてデータベースを一気に更新したい
しかし、SPIRAL®のPHP実行環境には「30秒」という実行時間制限があります。
大量のレコードを一度に処理しようとすると、処理の途中で30秒オーバーが発生し、タイムアウトでシステムが停止してしまうリスクがありました。
■【解決】サーバサイドの「ストリーミング出力」で完結させる
この制限を回避するため、実行環境のカスタマイズが容易な外部サーバを外部実行エンジンとして活用。
JavaScriptからはシンプルな同期処理としてリクエストを投げ、重たい処理のすべてを外部サーバ側にオフロードしました。

■技術的アプローチ:メモリを食いつぶさないデータ処理
単に外部へ処理を投げるだけでは、今度は外部サーバ側でメモリ不足やタイムアウトが起きてしまいます。そこで以下の工夫を凝らしました。
同期処理によるシンプル化:
フロントエンド(JS)側での複雑なループ制御を廃止し、サーバ側でSPIRAL APIとの通信から加工までを一貫して行うことで、通信のオーバーヘッドを最小限に抑えました。
ZipStream-PHPの活用:
ダウンロード処理では、全データをメモリに展開してから圧縮するのではなく、「生成しながら順次ブラウザへ流し込む(ストリーミング)」方式を採用しました。これにより、巨大なZipファイルもサーバのメモリを圧迫せずに安定して生成可能です。
結果として、SPIRAL®の堅牢さを活かしつつ、数十万件のデータを淀みなく処理できるパワフルなバックエンドを実現しました。
(次回「境界線の守り方 ―― JWT認証とセッション管理で実現する「ガチ」の防衛術」 に続く)