kifutown の設計とアーキテクチャ

kifutown の技術的な背景、大切に思っていること

ARIGATOBANK CTO の河津 (takuz0_) です。
7/24に kifutown をローンチし、早いもので1ヶ月が経ちました。

kifutown はリリース直後のトラブルでユーザーのみなさまにご迷惑をおかけいたしましたが、iOS アプリは一週間も経たずに50万件のダウンロードをいただき、その後も継続的に新規会員登録を賜っております。
(※Androidアプリも9月中にリリース予定です)

サービスを多くの方にご利用いただくにあたり、kifutown アプリのシンプルなUIの裏側について、この記事を皮切りに様々な視点からお伝えしていきたいなと思います。

全体アーキテクチャ

ARIGATOBANK のプロダクトでは以下の構成を標準的なアーキテクチャとして定義しており、kifutown も、後述する ARIGATO ID もこの構成で開発しています。

コードベースは GitHub で管理しモバイルアプリケーション/バックエンドアプリケーション共に CI/CD パイプラインを介してデプロイを行っています。

バックエンドのインフラには Google Cloud を全面的に採用しており、kubernetes を基本にして必要なマネジメントサービスを組み合わせることでサービスとして機能を提供しています。

マイクロサービスアーキテクチャ

kifutown は物事をシンプルに取り扱うことを優先し、オブジェクトやドメインごとにマイクロサービスとして1群のアプリケーションとして実装しています。

中核をなすマイクロサービス群には認証を管理する auth サービス、お客様の情報を取り扱う users サービス、寄付プロジェクトを取り扱う projects サービスなどがあり、それぞれ単一責任の原則に従い独立したDBへのアクセスを行います。

当然ながら users サービスが寄付プロジェクト情報を参照したいケース、projects サービスがユーザー情報を参照したいケース、もちろん場合によっては Write したいケースがあります。
こうしたケースに対応しつつビジネスロジックを漏れなく適用するために、マイクロサービス間呼び出しを行う API を定義し、それぞれの DB には必ず API を経由してアクセスすることを定めています。

kifutown ではそれぞれのサービス毎にトラフィックの性質が異なり、N万req/sec 下でも数個のコンテナ数で済むものもあれば、もっと広くスケールするものもあります。
このため現在は各マイクロサービス毎に pod を定義し、デフォルト稼働数やスケール数を設定しています。

ID, 認証/認可

先日当社CEOの白石が インタビュー でお話させていただきましたが、ARIGATOBANK では今後様々なサービスを創出していきたいと思っています。

仮に複数サービス複数アプリになった際にも、ご利用時に負担の少ない形にできるようにしていきたいということ、そしてお預かりする様々な情報を安全に取り扱えるようにしていくことを設計の初期段階から考慮に含めています。

このため各サービスを横断して ID を利用できるように、共通 IdP を ARIGATO ID として構築しています。

ARIGATO ID では Signup 時にユニークな内部識別子を生成し、ログイン時に入力していただく電話番号などは付帯情報として保存しています。
kifutown を含む ID サービスの利用側は ARIGATO ID と OpenID Connect で連携し、ARIGATO ID 上での識別子をユーザー情報に用いることで ID として利用しています。

余談ですが、フェデレーションされたユーザーのトークンの有効性検証の処理によって、ネットワークが輻輳してしまうというトラブルがありました。こうしたトラブルについての詳解や改善策なども改めて記事にしていきたいと思っています。

Codebase

monorepo… ではなく multirepo で構成しています。

これは必要なものから実装してきた歴史背景に起因するものではありますが、特にバックエンドアプリケーションは Go で現状はシンプルな依存関係を維持しているため、リポジトリのシンプルな運用を重視しています。
現在は GitHub Flow ベースのブランチ運用と CI/CD パイプラインで運用していますが、その時々で最適の尺度も変わってくるため、必要に応じて見直していきたいポイントです。

ただひとつ強く意識しているのは、
1 codebase ∈ N deploy(pipeline) ∋ 1 service の形です。
単一のコードベースから開発環境, ステージング環境, 本番環境にデプロイし、環境差分を CD パイプラインで反映させることで予期せぬ環境差分を回避するほか、環境固有の問題が起きないように努めています。

Programming Language

バックエンドアプリケーションは全て Go で開発しています。
シンプルで見通しの良いコード、フットプリントの小ささ、なにより並行処理の強さが主要な理由です。

モバイルアプリは Swift / Kotlin で開発しています。
よりよい体験をお届けするためにネイティブで細かな部分まで制御することを念頭に置いています。また9月に公開を予定している Android アプリは Jetpack Compose を全面的に採用するチャレンジをしています。

それぞれの言語選定の思想についてはそれぞれのアプリケーションアーキテクチャの解説と共に別の記事でお伝えしたいと思います。

Database

我々のアーキテクチャの中で特筆すべき点があるとすれば、データベースに Cloud Spanner を採用していることです。

公式の紹介ページにあるとおり「無制限のスケーリング、強整合性、最大 99.999% の可用性を備えたフルマネージド リレーショナル データベース」という点にアプリケーションでのデータ操作の多くの部分を依存しています。

非常に強い一貫性をデータベースの基本的なトランザクションシステムで実現できるため、アプリケーション側の実装をシンプルに保つことに大きく貢献しています。

また、ローンチからこれまでの kifutown のサービス性質上、どうしてもピークトラフィックがあるタイミングに集中しやすいというトラフィック特性と向き合う必要がありました。

kifutown ではプロジェクトへの応募が当選したか否かはもちろん、多くの処理でリアルタイムにデータ処理を行っています。これはすなわちオリジンへのアクセスを常に確保する必要があるということです。

Cloud Spanner は稼働状態でのノードスケールでも非常に高速にリシャーディングし、必要なタイミングに限定して性能を得ることが容易で、このことが我々のプロダクト運用の大きな助けになっています。

まだまだ Cloud Spanner の性能を十分に発揮させられているわけではありませんが、これからも最重要インフラとして多くの期待を持っています。

We are Hiring !

ARIGATOBANK では、今後も「お金で困っている人をゼロにする」ために様々な機能やサービスを創出していきたいと考えています。

今までにない未知のサービスを通して新しい未来を創る、そんなプロダクト開発に興味をもっていただけましたら、まずはカジュアルにお話できればと思いますので、お気軽に 採用ページ や Twitter の DM などからご連絡ください!

--

--

ARIGATOBANKエンジニアが書き綴るテクニカル記事集。思想や技術選定、課題や取り組みなどについて発信していきます。

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store