MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

2020年度新卒チームでRedisの管理システムを作った話

こんにちは。マイクロアド2020卒グループです。

マイクロアドのシステム開発本部では、新卒メンバーのみで1つのシステムを作る『開発研修』を2018年度から行っています。

過去年度の開発研修

2020年度の開発研修では、「Redis管理アプリ」を開発するという課題が与えられ、20卒のメンバーで開発を行うことになりました。 今回は開発したアプリの概要と工夫した点をまとめて記事にします。

Redisとは?

Redisとは、KVS(Key-Value Store)のデータベースで、インメモリであるため高速に動作します。マイクロアドのプロダクトにもRedisが採用されています。

Redisを長期運用する際にFailoverを繰り返すと、どのノードがマスタなのかといった構成情報が一見すると分かりづらくなることが問題点として社内から挙げられていました。

メンテナンス時に容易に状況を把握し、手動でFailoverなどの操作を行いたいという要望があり、今回の開発研修では「Redis管理アプリ」の開発が課題として与えられました。

設計

実際に開発を行う前に、まずは設計を行いました。先輩方にディレクションをしていただき、仕様の確認やRedisの操作についてのを相談をさせてもらいながら設計をしていきました。設計の大まかな順番は以下の通りです。

  1. 画面のレイアウト
  2. DB
  3. URL
  4. フロント・バックのアーキテクチャ
  5. 各クラス設計

画面のレイアウト

実際に作成した管理画面の様子
実際に作成した管理画面の様子

画面のレイアウト案を先に作ることは、ディレクターと仕様を確認するのにうってつけでした。レイアウトから入ることで、見た目・挙動がよりイメージしやすくなります。

DB

今回のWebアプリ内部で使用するDBはMySQLにしました。

仕様を把握しきれていないことや、Redisの構成をテーブルで表すことに苦戦したため、かなり試行錯誤しました。最終的にボツになったテーブル図の案は10以上もありました・・・。

DB設計で感じたことは、仕様を理解し切らないとDBのテーブル定義できないということや、必ずしもロールモデルの関係を表さずに、開発者がデータを扱いやすいような設計することも大切であるということです。

フロントエンド・サーバーサイドのアーキテクチャ

URLはフロントエンド側とサーバーサイド側で分けて考えました。フロントはVueRouterを用いたSPAにし、バックはREST APIにしました。

また、URLとそれに関するリクエストやレスポンスで扱うデータを共有するページを作って、フロントとバックの通信周りの開発はスムーズにいきました🎉

アーキテクチャは基本的に19卒の先輩方が開発研修で作成した「ぼーちゃん」を踏襲しています。

サーバーサイドはTERASOLUNAのガイドラインを参考にSpring BootDDDの戦術的設計のパターンの一部を取り入れています。

開発の前に、あらかたパッケージを作り、どのパッケージにどんなクラスを置くかを決めました。最終的には、以下のようなパッケージの構造になりました。

フロントエンド
├── App.vue
├── assets // 静的ファイル
├── main.ts
├── model // フロントで扱うオブジェクトの定義
├── pages // 画面
├── public
├── router // VueRouter
└── store // Vuexで扱うストア
サーバーサイド
├── application
│   ├── batch // 定期実行用スクリプト
│   ├── controller // コントローラ
│   ├── handler // 例外をキャッチしてハンドリングする
│   ├── helper
│   ├── request // リクエストのjsonを表すオブジェクト
│   └── response // レスポンスのjsonを表すオブジェクト
├── config
├── domain
│   ├── command
│   ├── exception // 例外
│   ├── model // ドメインモデル
│   ├── repository
│   └── service
└── infrastructure
    ├── command // linuxコマンドを叩く
    ├── dto
    └── repository // DBとのやりとり

各クラス設計

ここまで来たら、あとの設計はユースケースごとにクラス設計を行うだけです!

開発後に見返したら 開発終盤になって、「設計をもっとしっかりすればよかった〜」と20卒メンバーが口を揃えて言っていました。 開発するにつれて修正箇所が増えたり、柔軟な開発ができなかったりと、多くのメンバーが設計に課題を感じていたようです・・・。 とはいえ、開発が進んだからこそ気づけたこともたくさんあると思うので、そこは悲観せず。

※後日談:開発終了後、メンバーでちゃんとDDDを学ぼうと勉強会を何度かやってみたのですが、メンバーはRedis管理アプリを改めて設計し直したい気持ちでいっぱいになりました。

フロントエンド

フロントエンドで使用したフレームワーク、言語は以下の通りです。

  • フレームワーク : Vue.js
  • CSSフレームワーク : BootStrapVue
  • テストフレームワーク : Jest
  • 言語 : TypeScript

これらを選択した理由は、マイクロアドで開発しているプロダクトの一部や、ぼーちゃんがVue.jsやTypescriptを用いていることから、今後の業務につながったり、アドバイスが受けやすいと考えたためです。

CSSフレームワークとして使用しているBootStrapVueの公式ページでは、コンポーネントの動作をブラウザ上で編集しながら確認できるためとても便利でした。

また、開発は以下の流れで行いました。

  1. レイアウトの実装
  2. 各機能・画面の実装とテスト作成

今回フロントエンド担当になった2人はどちらも初心者ということで、開発初期の段階ではペアプログラミングをしながら進めていきました。

最初にレイアウトを実装することで、まず設計段階で作成したレイアウト通りに機能が実装できそうかを確認することができ、さらにVue.jsを用いたSPAの理解にもつながりました。

ある程度慣れたところで、次は各機能・画面ごとに役割分担をし、効率よく実装を行うことができました。

また、テストを作成することで与えられた仕様通りの動作をしているか、サーバーサイドと通信するためのAPIが間違っていないかを確認することができました。

反省点としては

  • 開発の途中になってVueXを導入したことで、VueXを使っている/使っていないところを統一ができていないまま進んでしまったこと
  • UI/UXについても、考慮不足のところがある
    • 戻るボタンの実装
    • タイトルロゴをクリックするとホーム画面に戻る機能
  • テストケースを増やす

などなど、まだまだ改修するべきポイントがあると感じました。

サーバーサイド

サーバーサイドで使用したフレームワーク・言語は以下の通りです。

  • フレームワーク : Spring Boot
  • 言語 : Kotlin

Spring Bootは社内の開発でよく使われているため、研修でも使用することにしました。使用言語は社内のサーバーサイドで使われている言語がJavaからKotlinに移行しているということを聞き、Kotlinを選択しました。

チーム内でどのようなレイヤーにするか試行錯誤した結果、下のような形になりました。

DBには管理対象のRedisの情報(portやhostなど)を保持しています。

内部の実装は上図のようになっており、フロントからRedis操作のリクエスト(PUT、POST)をアプリケーション層にあるControllerで受け取り、ドメイン層のServiceへと渡され、DomainObjectを介してインフラ層のRepositoryImplへデータを渡していきます。 DomainOnjectが操作対象のRedisのデータを保持し, Redisにコマンドを送る際はServiceからDomainObjectをインフラ層に渡し、Redisへ命令を送ります。

また、KrowMapperを用いることで、DBからEntityへのマッピングを楽に行うことができるため、開発効率を上げることができました。1

苦戦した点としては、Redisを管理するアプリケーションであるため、Redisに対しても知識が必要です。そのため、開発研修の前半ではRedisのコマンドの調査などに時間を取られてしまったことです。

インフラ

今回、インフラとして取り組んだのは

  • サーバーの初期化からOS環境整備までの調達
  • Jenkinsへの設定(CI)
  • 開発環境・デプロイ環境(Dockermaven、環境変数配布など)の整備
  • SpringSecurityでのOpenIDConnectを利用した認証

でした。構成は冗長構成を組んだWebアプリケーションサーバです。

社内のサーバー構成・運用ルール理解などに苦労しましたが、様々なミドルウェアを触ることができ、良い経験になったと感じています。

特に苦労した点は、SpringSecurityでのOpenIDConnectを利用した認証です。SpringSecurityは特に触らずとも様々な機能が利用できるため非常に便利です。しかし、その反面でデフォルトから外れた挙動を行う際はしっかり記述を求められることは良い勉強になりました。

終わりに

開発研修を通して「1つのアプリを設計から作る」という、今後の業務にも大変役立つ経験ができました。スケジュールに関してはだいぶ遅れてしまいましたが、それでも完成させることができて非常に安心しています。

このアプリ自体は社内で使われていくことと思いますので、今後も設計自体やUI/UXなどをアップデートしていきたいと考えています。

開発研修で得た経験を生かして、今後の業務や次年度以降の開発研修にも繋げられるよう、頑張っていきます。

ここまで読んでいただき、ありがとうございました!