Topazドラフト

どんなサービス

デスマ中のエンジニアを眺めながら金を落とす(予定)サービス

推しアイデア

作った背景

推し技術

今回は短期間にメンバーの多くの技術スタックを総動員して実装を行いました。
ざっと、取り上げられるものだけでこれだけあります!

  • k8s
  • Amazon IVS
  • kotlin
  • Rust
  • React
  • WebSocket
  • CI/CD(ステージング・本番構成)

主な突っ込んで欲しいポイント

  • ハッカソンでステージング・本番を用意しちゃった
  • 謎にガチガチなインフラ構成
  • ノリと勢いで投げ銭(お金じゃらじゃら機能)を追加
  • よくわからないライブラリも気合で動かし切った限界開発力
  • これまでのハッカソン資産を放棄し、kotlinで実装したバックエンド
  • ものの数日で社内ISUCONのプログラムをRustに移植した猛者

プロジェクト概要

インフラ

ライブ動画配信基盤

アプリの要となる動画配信基盤にはパブリッククラウドのAWSが提供しているAmazon Interactive Video Service (IVS)を使いました。これを用いることで一対多のライブ配信を実現させています。このサービスを活用することでバックエンドのタスクを削減することができます。Amazon IVSは再生用のSDKが容易されており今回はそれを利用して実行しています。

CDNキャッシュパージの自動化

クライアントの提供にはCDNであるAmazon CloudFrontを用いています。また、CloudFrontのオリジンサーバーとしてAmazon S3を用いています。クライアントをS3にデプロイするたびにCloudFrontのキャッシュを削除する必要がありますが通常操作であるAWSの管理画面からいちいちパージをするのは開発サイクルの高速化にはボトルネックです。今回はAWS LambdaとAWS SDKを用いて自動化させました。S3のオブジェクトが更新されることをキッカケに、対応するCloudFrontのキャッシュ削除をリクエストするように構成しています。

バックエンドの基盤にAmazon EKSを使用

インフラにはAmazon Elastic Kubernetes Service (EKS)
というマネージドなKubernetesサービスを用いました。使用きっかけは開発者の技術的興味によるものですが結果的には開発効率の向上に役立ちました。例えばnamespaceの活用により同じクラスター上に複数環境のコンテナをデプロイすることができたことやCDでデプロイした際に即時新しいイメージが適用されることが、開発速度を求められるハッカソンにはピッタリでした。

本番環境とステージング環境の用意

いつもハッカソンでは発表直前に環境を壊してしまうのはよくあることです。本番と全く同じステージング環境を用意して本番が壊れること防止しています。これにより仮にステージングが壊れようともデモで恥をかくことはありません。安心してステージング環境を壊せます!

CI/CDを構成

自動デプロイは最高です。それからフロントのlintチェックも行っています。今回は本番環境とステージング環境を用意しているのでその分だけGitHub Actionsのワークフローを用意しています。mainにプッシュするとステージングにtagでプッシュすると本番環境にデプロイされるようになっています。

以下はインフラ構成図です。

サーバーサイド

サーバーサイドでは以下のAPIを提供しています。

  • GitHub IssuesのStateからタスクの進捗率を計算するAPI
  • WebSocketを介したチャットサーバー

実装はKotlinで行い、Webフレームワークには純kotlin製のKtorを使用しています。
kotlinのwebフレームワークの代表例としてはSpringBootなどが挙げられますが、これらの比べシンプルでGo経験者でも比較的容易に実装できることから本フレームワークを採用しました。

チャットサーバーはパスパラメーターでチャットIDを付与し、同一IDを共有した人たちでブロードキャストが出来るようになっています。今回の実装ではフロントから送られたJSON形式のメッセージをそのままブロードキャストしています。メッセージオブジェクトのスキーマは以下のように定義しています。

{ "id":"example-user-id" // フロントのユーザーを識別するID "text":"hogehoge" // 投稿データ "action":"SEND_MESSAGE" // actionタイプ(SEND_MONEY or SEND_MESSAGE) }

クライアント

フロントアプリはReactで実装しました。以前まではReduxを使った状態管理を行なっていましたが、実装者の思想によりReactHooksを採用しています。
フロントアプリでは以下の機能を提供しています。

  • 配信画面
  • チャット機能
  • 進捗表示機能
  • (配信者専用)認証機能

配信部分のロジックはAWS IVSのライブラリを利用しています。チャットサーバーはブラウザAPIのWebSocketを用いてサーバーと通信を行なっています。テキスト投稿、投げ銭ボタン共にバックエンドのセクションで説明したJSONスキーマに従ってデータを投稿しています!なお、UIフレームワークにはBootstrapを採用しています。

今回、おまけで作った投げ銭機能について説明します。投げ銭機能はボタンを押すとジャラジャラとお金の音が鳴り、お金のアニメーションを動かすものです。アニメーションはCSSで実装しています。クライアントサイドで投げ銭をした時のサウンドと、誰かが投げ銭した時に連動して音が鳴る2つのパターンを用意しています。後者では投げ銭時にチャット基盤を通じてSEND_MONEYのアクションを発火し、アクセス時に生成される自身のランダムID以外の投稿時に音を鳴らすようにしています。こちらの機能は発表当日に突貫で作成したものなので、バグ等があった場合はご容赦ください。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
お金は配信者とあなたを幸せにする

コンテンツ

今回の目が離せないコンテンツは?

メンターのcatatsuyさんが公開している社内ISUCONのプログラムをRustに移植しました!(オリジナルはこちら: https://github.com/catatsuy/private-isu)

なお、ベンチマーカーですが、Rustの方が低いのはなぜでしょうか?データベースがボトルネックになっている

// Rust
{"pass":true,"score":9214,"success":8877,"fail":0,"messages":[]}
// golang
{"pass":true,"score":9414,"success":9075,"fail":0,"messages":[]}

最後に

私たちの技術スタックをアピールするために主だったものを全て書き連ねます。個々の理解の浅さには目を瞑ってください🙇

  • React
    • React Hooks
    • use-sound
  • WebSocket
  • Bootstrap
Select a repo