現在JavaScriptの設定が無効になっています。このページを利用するにはJavaScriptの設定を有効にしてください。2019の18日目の記事です。JAPANアプリの通知系バックエンドシステムを担当している福盛です。JAPANアプリの「お知らせ」画面のバックエンドシステムの刷新をテーマに、「刷新にあたっての設計」と「その開発過程」についてお話ししたいと思います。JAPANアプリの「お知らせ」画面は、現在アプリを通じて送信されたプッシュ通知の内容を一覧できる機能を提供しています。荷物の配送状況のお知らせヤフーの各種サービスからのお知らせなどです。上記の内容に加え、今後コンテンツの拡充を積極的に進めていくよう開発しています。システムの刷新〜PHPからScalaへ、仮想マシンからPaaSへ従来の「お知らせ」画面のバックエンドは、仮想マシンのクラスタに構築されたPHPで動作するプログラムでした。この構成は立派に動作しているものの、以下のような問題を抱えていました。Cassandra)の追加にともないコードの継ぎ足しが行われるため、改修が徐々につらくなっていく仮想マシンの管理、特にOSのセキュリティアップデートなどの対応に工数が取られる現在ヤフーでは全社をあげてシステムの刷新を行っています。大きな変化としては従来仮想マシンを使用していた部分をPaaSあるいはコンテナベースでの運用に切り替える使用プログラミング言語の見直しがあります。今回その流れに合わせ、「お知らせ」画面のバックエンドシステムを刷新することにしました。Service)を活用するようにしました。使用する言語はScalaを使うことにしました。僕の所属するチームでは1年ほど前からPaaS環境への移行に合わせScalaの採用を始めており、その記述の簡潔性と型安全性による品質向上効果を実感していました。PaaS上でのScalaによるシステムの運用についても十分なノウハウが蓄積されていたため、今回もこの流れに沿ってPHPからの移行を行うことを開発の初期に決断していました。その一方、今回の刷新プロジェクトのメンバーは半分以上がScala未経験という状況でした。設計〜変化に強い構造を意識する本格的な開発が始まる前に、全体の設計方針を決めました。Cassandra)へのアクセスAPIレスポンスの生成を単体のPHPプログラムが行っていました。今回の刷新に合わせ、変化に強い構造としてクライアントからのAPIリクエストを受け、レスポンスを返すコンポーネント(APIコンポーネント)レガシーなデータソースに接続し、その内容を取得するコンポーネント(データソースコンポーネントA)ここ1年ほどで作られた新しいデータソースに接続し、その内容を取得するコンポーネント(データソースコンポーネントB)の3コンポーネントからなるシステム構成を考えました。APIコンポーネントは2つのデータソースコンポーネントからHTTPでデータを受け、これらを整形した上でクライアントへレスポンスを返します。各コンポーネントの開発は独立して行うことができるクライアント−サーバー間のAPI仕様が更新された際に、APIコンポーネントの改修だけ行えば良い今後データソースが追加、廃止された際の改修が容易というメリットが得られます。システムを構成する3コンポーネントはいずれもWebアプリケーションです。World"レベル)のひな形がある状態まで進んだところで、本格的な開発に進みます。刷新のための開発プロセス開発が本格化する時点で開発プロセスも整備しておく必要があります。所属する部署では以前よりアジャイル系のプロセスを導入していましたが、今回はJIRAを活用してこれをさらにスムーズに回すことを試みました。JIRAを使う〜ホワイトボードは狭すぎる以前よりホワイトボート+付せん紙ベースでのカンバン、チケット管理は行っていましたが、チケットの数が多くなると管理が困難だったり、バーンダウンチャートを作るための作業のオーバヘッドが大きくなる(結果バーンダウンチャートの更新が遅れたり、作られなくなったりする)という問題がありました。多数のチケットがあっても困らない自動化により見積りの集計が容易になるエピックバーンダウンチャートで進み/遅れが把握できるようになるための手段として、今回JIRAの「エピック機能」を活用してみることにしました。初期チケットを切るまずエピック「お知らせ画面刷新開発」を新たに作成し、先に書いた設計方針から、実際に動くものを作るにはなにが必要かを考えながら、バックログにチケットを切っていきます。チケットは軽く、でもやることが分かるようにそれぞれのチケットには紙ベースでやっていたときと同様、(付せん紙におさまるくらいの長さの)簡単なタイトルをつけて行きます。JIRAのチケットにはさまざまな情報を書く機能がありますが、それらは使いません。今回特に意識したのはチケットを「〇〇コンポーネントは△△できる」といった、「主語-述語」で書けるストーリーとして記述することです。APIコンポーネントはJSON形式のスタブレスポンスを返却できるデータソースコンポーネントAは起動時にMySQLへ接続できる...といった具合です。コンポーネントを主語にすることで、そのコンポーネントの実現すべきことを明確に、また完了条件を明確にするという効果を狙っています。このようにして30個ほどの初期チケットを作成しました。見積りはTシャツサイズ法で初期チケットをそろえたところで各チケットの工数見積もりを行います。L=8の数字を割り振るようにしました。迷ったときは一つ上のサイズを選ぶことL(=8)を超えるようなチケットがある場合には必ず分割するを意識して見積もりとチケットの分割を行っていきます。チケットはいつでも並べ替えられるように工数まで入ったチケットがそろったところで、どこからどの順番で進めるかを考えます。JIRAのバックログはドラッグアンドドロップにより、チケットの順序を自由に並べ替えられるのでこれを活用しました。メンバーが半分以上のため、Scalaや使用するWebフレームワークの習熟を開発と並行して行わなければなりません。今回はこれらの問題に対し、以下の手を試してみました。Requestの活用まず開発の立ち上げ時に用意したWebアプリケーションのひな形を原型として、各コンポーネントの基本形を用意する、そこからスタブのJSONを返すよう改修していく、という作業を、経験者と新規参加メンバーのペアプログラミングというかたちで始めました。ある程度感覚がつかめてきたところで、新規参加メンバー同士でのペアプログラミングも行います。これにより一人ではハマる状況を回避しながら、メンバー間でコンポーネントの理解を進める効果を得ています。Requestによるレビューも重要です。Requestを発行したりといった工夫を行いました。コンポーネントに担当者が張り付かないようにするかつてのプロジェクトで、各コンポーネントにそれぞれ専任の担当者がついて開発を進めるという方式で進めたことがありました。「あるコンポーネントの進行でハマると他の人が助けられない」「コンポーネント間でのつなぎこみでインターフェースの齟齬が生じやすい」という問題が開発後半に現れ、苦労しました。今回は3つのコンポーネントからなるシステムですが、このような問題を回避するために「コンポーネントに担当者を割り当てない」よう注意しました。先に述べたペアプログラミングもこの方針を進める上で効果があったと思います。実際、開発の中盤で(別件などが立て込んで)僕の開発の手が止まってしまったとき(恥ずかしいことですが)、他の開発メンバーが僕の持っているチケットを肩代わりして進めてくれたことがあり、非常に助かりました。進行は「エピックバーンダウンチャート」を活用する従来の開発では進行状況をカンバン上の付せん紙の移動の様子でなんとなく把握しようとしていましたが、全ての開発チケットがカンバンの上に載らないままスプリントが進んでいくため、終わりがよく見えない状態が発生することもありました。付せん紙で見積もりの数字を書きつつ、バーンダウンチャートを書いていく方式も集計やグラフ作成の手間が大きく、いま一つ決め手に欠ける状況が続いていました。今回はJIRAの「エピックバーンダウンチャート」を活用して、開発全体の進行度合いを可視化させることを試みました。JIRAの「エピックバーンダウンチャート」は「エピック」という単位でまとめられたチケットの総工数とその消化度合いをもとに、現在の進行度と完了見込みを可視化する「バーンダウンチャート」を自動的に計算、表示させる機能です。JIRAの「エピックバーンダウンチャート」は少なくとも3スプリント(本プロジェクトでは3週分)のチケット消化記録がないと表示されないなど、小回りが効かず不満の残る部分もありますが、集計とグラフ化をすべて任せることができる点は大変重宝しました。開発終盤〜増えるチケットと着地点の折り合い開発が進行していくとチケットが消化され、バーンダウンチャートも週ごとに低くなっていきます...が、同時に設計と開発初期には分からなかった課題が新たなチケットとして登場します。開発終了予定の時期が近づくとどうしても全部をクリアすることができない状況も当然発生します。その際、バックログに置かれたチケットを「やるべき順」に並べ直し、下の方にあるチケットをやらないと判断する過程が必要です。これを実現する場合には、先に述べたようにチケットは「〇〇コンポーネントが△△できる」という書き方で統一し、かつそれぞれのチケットは独立していることが重要です。今回の開発でもリリース後の改修で対応するものを切り出して別のエピックに移動させるなどの措置をとりましたが、最終的なチケット数は初期に立てたチケットの約2倍弱となっています。それでもメンバーの頑張りと関係部署との調整により、予定された開発完了期日を大きく外すことなく開発を完了することができました。設計時に特に意識していたのは、「将来レガシーなデータソースを切り離せるように作る」という点でした。システムの改修ではコードや機能の追加ばかりがクローズアップされますが、古くなったものを削除したり廃止したりすることも今後重要となると考えたためです。データソースとAPIをHTTPサーバーで結ぶ構成は純粋なパフォーマンスの観点からは不利ではありますが、データソースの廃止やコードの削除を最小限の手間で行えるという利点があります。効果については今後そのような状況が発生した際に、改めて検証してみたいところです。まとめ〜開発は学習過程、プロダクトはソフトウェアとチーム今回はチームの半数以上がScala未経験という状態から始めたプロジェクトでしたが、なんとか無事に完了させることができました。参加メンバーには大変感謝しています。従来のPHPベースのシステムと比較して、改修版のシステムはScalaを採用したことによるバグ低減効果、コンポーネントを分けることによる不具合の発見と修正の効率化、PaaSを採用したことによる共通インフラ(アプリケーションログ検索、パフォーマンス解析システムなど)の活用といったメリットを大いに実感できるものとなりました。これらの詳細についてはぜひ別の機会に紹介したいと思っています。このプロジェクトが一段落して改めて思ったのは、開発とは技術や要件を理解していく、いわば「学習過程」とでも呼ぶべき活動である、ということです。JAPAN公式アプリとのAPI仕様」「PaaS環境でのリリース・運用」など多岐にわたります。JAPAN公式アプリのバックエンドを開発、運用、改修ができるチームであるとも言えます。「システム」と「チーム」、この2つの資産を増やして、よりよい仕事をしていくことが今後私たちに求められていることではないかと思うのです。今回の開発プロセスは基本的に以下の本を参考にしています。訳アジャイル系開発プロセスの要点をまとめた本として、とても分かりやすい一冊です。発売から8年たちますが、原点に戻るためにたびたび読み返しています。JAPANアプリの通知系処理をメインに担当しています。JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。JAPANのサービス開発を支える技術やデザイン、文化を発信しています。Reserved.このページの先頭へ。