# 「Icey」の開発
## プロダクト概要
会員制動画配信サービス「[Icey](https://icey.jp/)」の新規開発・運用をしていた。
一言で言うと、**自身の動画コンテンツを限定公開・売買する**Webアプリケーション。
イメージとしては以下の様な感じである。
- Udemyの様に、自身の動画コンテンツを販売できる。
- CMSの様に、自分専用のサイトを簡単に構築できる。
## プロジェクトの規模
- **開発メンバー:** 4人(全員日本人、全員業務委託)
- **開発期間:** 2021年5月〜2021年11月(7ヶ月)
## 技術スタック
| | 技術スタック |
|--------------------|--------------------------|
| フロントエンド | Haml, jQuery |
| バックエンド | Rails |
| DB | MySQL, Redis |
| インフラ | AWS, Docker, CircleCI |
| 開発支援ツール | GitHub, Slack |
## 担当役割
フェーズとしては、`0→1`と`1→10`を経験。
フルスタックエンジニア 兼 Tech Lead 兼 EM 兼 PjM(PdM未経験)として、以下の重要な役割を担当:
- インフラの設計・実装・運用
- バックエンドの底上げとチームビルディング
- CircleCIを利用したCI/CDパイプラインの構築
- メンバーのタスクマネジメント
## インフラの設計・実装・運用
### 前提
- **私以外のメンバーがインフラ未経験だった**ので、全てのインフラ業務を一人で担当した。
### 成果
<!-- 具体的には、以下のサービスを利用
- IAM
- VPC, Route53, ACM
- ALB, TargetGroup, Athena, AWS WAF, Kinesis FireHorse
- CloudWatch, SNS, Chatbot
- S3, CloudFront
- RDS, Redis
- EC2, ECS/ECR, CloudFormation, AutoScaling
- Lambda, MediaConvert -->
1. ゼロから一人でインフラ構築
**私以外のメンバーがインフラ未経験だった**ので、全てのインフラ業務を一人で担当した。
2. `CloudWatch`, `Performance Insight`, `Athena`を用いたパフォーマンスの可視化とログ解析
- **課題**
新規開発サービスなのでリリース時のアクセス数に予測がつかない状態だった。
- **解決策と工夫点**
そこで、`CloudWatch`を用いて`CPU/Memory使用率` や `ALBのレスポンスタイム`, `StatusCode`などが一定の閾値を超えると`Slack`に通知することで、**チーム全員が即座にパフォーマンス悪化を確認できる様にした**。
また、`Performance Insight`, `Athena`を導入し、ログ解析・原因の早期発見・改善を実現した。
3. `AutoScaling`と`マルチAZ`構成用いたスケーラビリティを実現し、高負荷時でもダウンタイムをゼロに成功
- **課題**
サービスの特性上、アクセス数が急増することが予想された。
- **解決策と工夫点**
`マルチAZ`, `AutoScaling`を用いてアクセス数に応じて`EC2`を自動で増減させることで、アクセスのダウンタイムをゼロにした。
4. コストとセキュリティを加味したAWSアーキテクチャの採用でコストを`50%削減`に成功
- **課題**
予算が限られていたので、コスト削減が求められた。
- **解決策と工夫点**
- `ECS`を`Fargate`ではなく`EC2`を使い、コスト削減を実現
- `WAF`を用いて、`SQLインジェクション`や`DDoS攻撃`からプロダクトを保護(実際、めっちゃDDoS攻撃きててヤバかった)。<!-- (海外からのリクエストをブロックしたらStripe死んだ) -->
- 敢えて`Public Subnet`のみを使うことでコスト削減を実現(`EC2`や`RDS`は`SG`を用いてリクエスト元を制限)。
`Private Subnet`では`NATゲートウェイ`が必要になり、使用時間とデータ転送量でお金がかかる。
動画配信サービスなのでデータ転送量が多いとコストに跳ねそうだったので、敢えてパブリックサブネットのみを使うことでコスト削減を実現した。
5. `Route53`の`CLI`を活用し、CSの業務時間を`月30時間削減`に成功
- **課題**
サービスの仕様として、動画コンテンツを配信するユーザーは各々`test.icey.jp`のようにサブドメインを発行して専用サイトを作る。
初期仕様ではユーザーがサブドメインをリクエストし、CSが都度サブドメインを登録するフローになっていた。
しかしそれではスケールしない && ヒューマンエラーの温床になる状態だった。
- **解決策と工夫点**
サブドメイン自動登録バッチを実装したことで、**ドメイン発行処理を自動化し月30時間削減に成功**した。
6. `Lambda`, `MediaConvert`, `CloudFront`を用いて動画再生のUX向上に成功
- **課題**
ユーザーがアップロードした動画の解像度が大きいと再生が遅くなる懸念があった。
- **解決策と工夫点**
動画アップロードを契機に`MediaConvert`を起動し、`HLS`形式に変換・解像度変換処理を実装し、`CloudFront`を用いて動画のキャッシュすることでUX向上に貢献した。
## バックエンドの底上げとチームビルディング
### 前提
- **私以外のメンバーがプログラミングスクール卒業したばかりの実務未経験エンジニアだったので、可読性やパフォーマンス、セキュリティ的に良くないコードが散見されていた**。
`Cost`は良いが、`Quality`, `Delivery`が最低だったので、以下取り組みを通じで、バックエンドの底上げを行った。
### 成果
1. 技術力の底上げ・属人化の排除に貢献①
- **課題**
- そのコードを書いた人しか読めないコードが多発していた。
- 自分以外のメンバーは全員エンジニア歴が浅く、単純に実力不足だった。
- **何が分からないかを分からない**状態だったので、課題の吸い上げやエスカレーションが無い状態だった。
- **解決策と工夫点**
ペアプロ・モブプロを通じてメンバーとのコミュニケーション・教育を徹底することで技術力の底上げ・属人化の排除に貢献した。
2. 技術力の底上げ・属人化の排除に貢献②
- **課題**
`PRレビュー`やペアプロ・モブプロでは時間的限界があった。
- **解決策と工夫点**
`Brakeman`や`Bullet`, `lol_dba`, `Rubocop`を導入し、セキュリティ脆弱性やパフォーマンス問題、コードの可読性などをシステマティックに特定・修正させることで、漏れなくコードの品質向上に成功した。
3. 技術力の底上げ③
- **課題**
メンバー全員やる気はあるものの、自分以外はエンジニア歴が浅く知識や経験が不足していた。
- **解決策と工夫点**
週1回1時間の社内勉強会を実施することで、技術力の底上げ・コミュニケーション促進化にも貢献した。
4. プロダクト品質の向上
- **課題**
`Quality`より`Delivery`優先で、**テストが一切実装されておらず、プロダクトの品質を保証する根拠が全くない状態**だった。
- **解決策と工夫点**
全くテストを実装せずに開発を続けるのは危険ではあるものの`Delivery`最優先だったので、
プロダクトのコアドメイン(動画やユーザーのCRUD)に限定して、単体テスト(RSpec)を実装した。
これにより、**最低限の品質を担保しつつ開発スピードを維持できるように貢献**した。
これらを通じてメンバーの技術力の底上げに成功し、コードの品質向上や属人化を排除に貢献した。
## CircleCIを利用したCI/CDパイプラインの構築
### 前提・課題
- **私以外メンバーはインフラ・デプロイ周りの知見が全く無いので、デプロイの時間帯は私の作業時間に依存していた**。
- デプロイスクリプトを実装したが、他メンバーが`M1 Mac(Apple Silicon)`を使っていてCPUアーキテクチャが異なり、結局`Docker`イメージが動かないという問題が発生した。
(`EC2`の`CPU`が`Intel`製の`x86`アーキテクチャにも関わらず、`M1 Mac`でビルドされたイメージは`arm`アーキテクチャだから。)
### 成果
- 開発スピードが属人化しないように、**`CircleCI`を提案・導入し、開発スピードの向上に貢献**した。
## メンバーのタスクマネジメント
### 前提
**私以外のメンバーがプログラミングスクール卒業したばかりの実務未経験エンジニアだったので、シンプルにタスクマネジメントができていなかった**。
### 成果
1. スケジュール遅延の改善
- **課題**
- **PjMがいなかった。**
- スケジュール遅延が常態化していた。
- 自分以外のメンバーはエンジニア歴が浅く、タスク・スケジュール・スコープマネジメントが全く出来ていなかった。
- **解決策**
なんちゃってスクラム(スクラムの`型`のみ導入し、`思想`は導入しない)の導入。
- **工夫点**
スクラムの`思想`までちゃんと導入するには自分もメンバーも知識不足で失敗する可能性が高かったので、**プロジェクト管理の手段としてスクラムを導入**した。
具体的にはプランニング・スプリントレビュー・レトロスペクティブのみ導入し、スプリントごとにタスクの細分化・割り振り・締切設定をすることで、スケジュール遅延を大幅に改善できた。
また、スプリントごとに簡易的なレトロスペクティブをを行い、メンバーの成長・自主性の向上に貢献した。
<!-- ## 反省(メモ)
- ポジションの兼務は利害相反になりやすいので、長期的には良くない。でも、他に任せれる人がいなかったのでしゃーないかも。
- メンバーのタスク管理については、マイクロマネジメントだったかも。でもレベルが低すぎたから、それしか手段がなかったかも。
マネジメントはコマンドアンドコントロール型とサーバントリーダーシップ型がある。
ジュニアメンバーは自分でタスクを進めることもエスカレーションもまともにできないので、コマンドアンドコントロール型が適している。
対して、ミドル・シニアになると、マネジメントが二度手間になるので、サーバントリーダーシップ型が適している。
- 技術的な正しさを追い求めていたかも -->