SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

LINE DEVELOPER DAYレポート

期間は6日間、LINEはいかにして新型コロナ対策全国調査を開発したのか

LINE DEVELOPER DAY 2020 レポート

開発の際に意識した3つのポイント

 今回の調査はLINEユーザー全員が対象である。そのため多くの回答が寄せられることが想定され、それを処理できるシステムの構築が必要だ。またシステムトラブルによって停止することはあってはならない。「システムトラブルが発生すると、調査にご協力いただいているユーザーに迷惑をかけることになる。我々が信頼を失うだけではなく、社会に対するネガティブな印象を与える恐れがあった」と小川氏はその理由を述べる。

 そこで次の3つのポイントを意識して開発を進めたという。

 第一に必要最小限の仕様のみを実装し、極力シンプルなシステムをつくること。第二に段階的に開発を進めること。システムが動作可能な状態を維持しつつ、段階的に拡張していくことで、不確定要素の多い開発でも柔軟に対応できるからだ。「本プロジェクトでは開発スタートの時点で仕様が固まっていなかった。それを待つ時間がないため、開発の進行状況を見ながら、どこまで仕様を盛り込むか決めていかざるを得ませんでした」(小川氏)

 第三はシステムトラブルをできる限り、設計段階で回避すること。「短期間での開発なので、各コンポーネントを十分に作り込めない可能性が通常よりも高い。その中でも目に見える形でのシステムトラブルを回避できるよう設計を工夫しておくことが重要だと考えました」(小川氏)

 最初のステップで取り組んだのは調査ページを表示する仕組みと、回答データを保存する仕組みの実装である。今回の調査はユーザーがメッセージを受け取ることから始まる。そのメッセージには調査への回答のお願いと最初の設問が表示されており、その設問に答えると調査ページが表示され、続きの設問に回答できる。調査ページはLINEアプリ内ブラウザで表示している。回答を送信するとサンクスページが表示される。

 これらの機能を短期間で実装し、かつ安定的に大量のトラフィックを処理するため、Nginxを中心に構成することを決めたという。同社ではこれまでもNginxを利用してきた実績があったからだ。

 回答フォームを設置した調査ページは、静的なHTMLとしてサーバから返す仕組みとし、設問の内容はデータベースに格納することなく、ページ内にハードコードすることにしたという。「今回の調査ではメッセージ内の回答の内容によって、調査ページの設問を切り替える仕様にしていたが、その処理はJavaScriptで行うようにし、サーバ側ではユーザーによってページの出し分けが必要のない形にしている」(小川氏)

 ユーザーが回答をし終えると、その内容をサーバに送るリクエストが発生する。この回答の送信処理は次のように2段階で実施している。まず調査ページを開くタイミングでメッセージ内の設問への回答を送信し、次にすべての設問に回答したタイミングですべての回答を送信するのである。「この仕組みによって、ユーザーが途中で離脱しても最初の設問の回答だけは集計できるようにしています」(小川氏)

 回答を保存する部分についても、Nginxで実現している。回答内容をアクセスログの一部として書き出し、集計しやすいようLTSV形式で出力するのである。「ここでポイントになるのは、リクエストボディを保存していること」と小川氏は指摘する。クライアントからのリクエストでは、HostリクエストのボディにJSON形式で回答データを埋め込み、これをLTSVのフィールドの1つとしてそのまま保存するのである。このようにすることで、設問の内容が変わっても、Nginxの設定の更新が不要になる。「サーバーサイドとしては設問の変更に影響されないように設計にし、クライアントと分析側のみで対応できるようにしました」(小川氏)

 第二ステップで取り組んだのは回答ログの集約部分の実装である。回答データが含まれたアクセスログは、アプリケーションサーバの各ホストのディスク内に書き込まれる。最終的に調査結果としてまとめるためには、1カ所に集約する必要がある。もちろん、ログの集約は調査期間の後でもできるため、第一段階で構築したシステムだけで調査を行うこともできる。だが「仕様検討をしていく中で、調査の進行中にリアルタイムに近い形で回答ログを集約すべきだと判断し、実装することにした」と小川氏は明かす。

 その目的は大きく2つある。一つ目はモニタリングのためである。ログの蓄積情報を随時確認できることで、システムトラブルが検知できるようになり、より安定した調査の実施が可能になることだ。もう一つは回答数を最大化する施策への活用である。まだ回答していないユーザーだけに回答をお願いする施策を実行することができる。

 リアルタイムなログ収集を実現するためのツールとしては、fluentd、ログの収集先としてMySQLを採用。アプリケーションサーバの各ホストにfluentdを導入し、アクセスログの更新を監視すると共に、追記されたログを1秒に1回、MySQLのテーブルにインサートする。またfluentdを利用してアクセスログを呼び出すことで、ログの集約処理をユーザーのリクエストに対する処理とは非同期に行うことができる。「非同期にしたのは、ログの集約部分で不具合があったときにユーザーが調査に回答できなくなるリスクを低減するため」と小川氏は説明する。

 第三ステップでは、ログを検証してフィルターする処理を実装。最終的な調査結果では、各ログのリクエストが正規のものかを確認し、不正なリクエストについてはフィルターする必要がある。加えて本調査は何回でも回答できるような仕組みとなっているため、複数回回答した人は、最後の回答を有効とするという仕様にしていた。Nginxではユーザーが回答済みかどうかはチェックできないため、保存された回答データに対して、後からチェックして、同じユーザーからの回答をフィルターする必要があったからだ。「ログの検証については、リアルタイムに近い形で実現する必要はなかったが、モニタリングが正確にできるメリットがあったことと、実装がそれほど難しくなかったことから、ほぼリアルタイムに近い形で検証する方針に決めました」(小川氏)

 回答を行ったユーザーの識別には、LINEログインを利用している。LINEログインのシステムでは、ログイン時にIDトークンを発行して返し、そのIDトークンをイベント送信時にリクエストに含めてサーバに送る。発行されたIDトークンは公開鍵を使って内容を検証することで、正規な発行元から発行されたトークンかどうかを検証できる。またIDトークンは発行されてから一定期間有効なので、少し遅れて検証することもできるからだ。

 このようなIDトークンの特徴を生かすことで、発行されたIDトークンをいったんDBに保存し、非同期に検証するという構成を取ることが可能になる。アクセスログに含まれるIDトークンを検証し、その結果をMySQLの別のテーブルに書き戻す。同時にユーザーがすでに回答済みかどうかをチェックし、回答済みなら、元の回答に上書きする形で保存する。「ログの検証はCPUに負荷がかかる処理であるため、アプリケーションサーバと別のサーバで非同期に行うことで、ユーザーからのリクエストに影響が出ないようにしました」(小川氏)

今回開発したシステムの最終的な設計
今回開発したシステムの最終的な設計

次のページ
メッセージの配信ペースにも工夫を

この記事は参考になりましたか?

LINE DEVELOPER DAYレポート連載記事一覧

もっと読む

この記事の著者

中村 仁美(ナカムラ ヒトミ)

 大阪府出身。教育大学卒。大学時代は臨床心理学を専攻。大手化学メーカー、日経BP社、ITに特化したコンテンツサービス&プロモーション会社を経て、2002年、フリーランス編集&ライターとして独立。現在はIT、キャリアというテーマを中心に活動中。IT記者会所属。趣味は読書、ドライブ、城探訪(日本の城)。...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/13306 2021/02/03 11:00

おすすめ

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー