Slide 1

Slide 1 text

FAANSを支えるアーキテクチャ
 2022/02/17 ZOZO.go Meetup
 株式会社ZOZO
 メディア開発本部
 本部長
 脇阪 博成 Copyright © ZOZO, Inc.

Slide 2

Slide 2 text

© ZOZO, Inc. 株式会社ZOZO
 メディア開発本部
 本部長 脇阪 博成
 2019年6月入社
 入社後はWEARのリプレイス開発、組織マネジメントを行い、 その後はFAANSの開発責任者としてサービスをローンチ。
 2021年10月から本部長に就任し、両プロダクトの開発組織 のマネジメントを行う。
 
 
 2

Slide 3

Slide 3 text

© ZOZO, Inc. 3 Agenda
 
 1. FAANSとは
 
 2. FAANSのアーキテクチャ
 
 3. コード生成の工夫
 
 4. 失敗(と言い切るほどではないが)談
 
 5. まとめ


Slide 4

Slide 4 text

© ZOZO, Inc. 4 1. FAANSとは


Slide 5

Slide 5 text

© ZOZO, Inc. 5 FAANS is Fashion Adviser Are Neighbors
 
 ECでお買い物を楽しまれるお客様とショップスタッフの新たな接点を創出し、ショッ プスタッフの効率的な販売をサポートするショップスタッフ専用ツール。ZOZOTOWN が持つECでの販売ノウハウと、ショップスタッフが持つ実店舗での販売ノウハウを 掛け合わせ、オンラインとオフラインをシームレスにつなぐ新たな販売方法を実現し ます。
 
 https://droidkaigi.jp/ninjas/post/zozo/
 


Slide 6

Slide 6 text

© ZOZO, Inc. 6 画面イメージ


Slide 7

Slide 7 text

© ZOZO, Inc. 7 FAANSの機能
 ● 招待制のtoB向けアプリ
 ○ iOS, Androidアプリをストアに公開中
 ○ 管理者向けの機能としてWebアプリも提供中
 ● 主な機能
 ○ アカウント、企業管理
 ○ 店舗在庫連携
 ■ ZOZOTOWNのAPIを利用
 


Slide 8

Slide 8 text

© ZOZO, Inc. 8 2. FAANSのアーキテクチャ


Slide 9

Slide 9 text

© ZOZO, Inc. 9 インフラアーキテクチャ概観
 出典: https://techblog.zozo.com/entry/sre-work-for-cloudrun

Slide 10

Slide 10 text

© ZOZO, Inc. 10 FAANS技術スタック#1
 開発言語
 
 Go(レイヤードアーキテクチャ)
 
 コンテナ実行基盤
 
 Cloud Run
 
 DB
 
 Cloud Firestore
 
 
 非同期ジョブ
 
 Cloud Tasks
 
 外部連携
 
 Cloud Pub/Sub
 
 ファイルアップロード
 
 Google Cloud Storage
 
 
 


Slide 11

Slide 11 text

© ZOZO, Inc. 11 FAANS技術スタック#2
 認証
 
 Firebase Authentication
 
 Push通知
 
 Firebase Cloud Messaging
 
 ホスティング
 
 Firebase Hosting
 
 
 メール
 
 Amazon SES
 
 
 
 
 


Slide 12

Slide 12 text

© ZOZO, Inc. 12 今日話すこと
 開発言語
 
 Go(レイヤードアーキテクチャ)
 
 コンテナ実行基盤
 
 Cloud Run
 
 DB
 
 Cloud Firestore
 
 
 本資料ではこの3点を掘り下げます


Slide 13

Slide 13 text

© ZOZO, Inc. 13 Goの選択理由#1
 ● プロトタイプはRuby on Railsで開発していた
 ● Rails選択の理由
 ○ WEARでRailsを使っていたこと
 ○ WEARのエンジニアを異動させる想定だったこと
 ● 一方でWEARでRuby on Railsの難しさを感じていた
 ○ 未経験者が書く動的型付け言語の品質
 ○ どこにコードを書けばいいか迷子になることがある
 ■ model? controller? 独自のservice?
 ● 全体的にレビューコストが高くなっていてモヤモヤしていた


Slide 14

Slide 14 text

© ZOZO, Inc. 14 Goの選択理由#2
 ● WEARからの異動の選択肢がなくなった
 ○ 採用する or 他の部署からの異動
 ● 全社技術スタックが策定されJava or Goが強く推奨された
 ○ https://qiita.com/sonots/items/629b8d5785c04ae9c953
 ● これらを理由にGoで書き直すことを決断
 ● 合わせて前述した迷子問題を解決するためにレイヤードアーキテクチャを選択


Slide 15

Slide 15 text

© ZOZO, Inc. 15 レイヤードアーキテクチャ
 ● 割と一般的なレイヤードアーキテクチャを採用
 ● レイヤーごとの責務を明確にし、どこに実装すればよ いかの迷子を発生しにくくした
 ○ なれないうちは迷子が発生するが、レビューの指針 があるのとないのでは大きく違う
 ● コードの記述量が増えるという欠点があるが、コード 生成で負担を軽減している
 


Slide 16

Slide 16 text

© ZOZO, Inc. 16 Cloud Runの選択理由
 ● Go 1.16を利用できるコンテナ実行基盤
 ○ GCPの場合この時点でCloud RunかGKEの2択
 ● リリースまで時間が限られており、SREのリソースが不足していた
 ● Cloud Runはシンプルで素早く利用開始でき、GCPサービスとの連携も容 易
 ● 基本的には素晴らしい


Slide 17

Slide 17 text

© ZOZO, Inc. 17 3. コード生成の工夫


Slide 18

Slide 18 text

© ZOZO, Inc. 18 controller(interface)
 ● OpenAPIの定義に基づいてopenapi-generatorでコード生成している
 ○ 公式で生成されるものはレイヤードアーキテクチャと相性が悪い
 ○ Javaとmustacheで自前のものを用意して運用している
 ● 最近はRESTを捨て、すべてPOSTリクエストにしている
 ○ アプリはAPIクライアントを自動生成していて、RPCのように扱っている
 ○ そのためパスパラメータやクエリストリングを意識することはない
 ○ サーバ実装も全部Bodyできたほうがデシリアライズしやすい
 ● そこまでやるならgRPCで良かったのでは???
 ○ そう思います


Slide 19

Slide 19 text

© ZOZO, Inc. 19 controller(interface)の生成物のサンプル


Slide 20

Slide 20 text

© ZOZO, Inc. 20 adapter zozo_apiについて
 ● ZOZOTOWNのOpenAPIの定義をもとにopenapi-generatorでコード生成


Slide 21

Slide 21 text

© ZOZO, Inc. 21 adapter firestoreについて
 ● こちらもスキーマ定義に基づいて自動生成しているが…
 ● その前になぜFirestoreを選択したのかを説明します


Slide 22

Slide 22 text

© ZOZO, Inc. 22 Firestore
 ● FAANSはマルチテナントなアプリケーション
 ● RDBでマルチテナントの実現は、すべてのテーブルに テナントIDを仕込む運用で辛い
 ○ DBを分離する方法もあるのだが、今度はマイグレー ションが辛い
 ● Firestoreにはサブコレクションという概念がある
 ● ルートコレクションをテナントにすることで、安全に分離 できるのではと考えて採用した
 ● GCPに全寄せしたかった、使ってみたかったなどの理 由もある
 ※サブコレクションのイメージ図 出典: https://firebase.google.com/docs/firestore/data-model?hl=ja

Slide 23

Slide 23 text

© ZOZO, Inc. 23 FirestoreはスキーマレスなNoSQL
 ● スキーマレスと型のあるGoの相性は悪い
 ● 実装をミスると正しくサブコレクション以下にデータが作られないこともある
 ● 単純なCRUDを都度実装するのは手間
 
 上記問題が実装時に発覚
 スキーマを定義してO/Rマッパー風のコードを自動生成してこれらの問題の解決へ


Slide 24

Slide 24 text

© ZOZO, Inc. 24 Protocol Buffersによるスキーマ定義


Slide 25

Slide 25 text

© ZOZO, Inc. 25 Protocol Buffersについておさらい
 ● Googleにより開発されているインターフェース定義言語
 ○ gRPCにも使われている
 ● 一般的なユースケースは通信や永続化の際のデータシリアライズに利用すること
 ● Protocol Buffersの本質はスキーマ定義
 ○ 簡素
 ○ 可読
 ○ protocとそのプラグインによるコード生成
 
 


Slide 26

Slide 26 text

© ZOZO, Inc. 26 protocプラグイン
 ● protocコマンドはprotobufスキーマからクラスや構造体を生成するcompiler
 ○ C++, Java, Python, Rubyなどがサポートされている
 ● 他言語のための拡張機構が用意されていて、それがprotocプラグイン
 ● これを利用することでスキーマ定義から様々なコードを生成できるようになる
 


Slide 27

Slide 27 text

© ZOZO, Inc. 27 Protocol Buffersによるスキーマ定義(再掲)
 


Slide 28

Slide 28 text

© ZOZO, Inc. 28 protocプラグインの生成物1
 スキーマに対応した構造体を生成

Slide 29

Slide 29 text

© ZOZO, Inc. 29 protocプラグインの生成物2
 コレクションに対する操作を行うメソッドを生成

Slide 30

Slide 30 text

© ZOZO, Inc. 30 protocプラグインの生成物3
 ドキュメントに対する操作を行うメソッドを生成 サブコレクションを取得するメソッドも生成 これによりスキーマ通りにデータを作成、取得することを強制

Slide 31

Slide 31 text

© ZOZO, Inc. 31 その他に利用しているコード生成ライブラリ
 ● wire
 ○ DIライブラリ
 ● moq
 ○ Mock生成ライブラリ
 
 


Slide 32

Slide 32 text

© ZOZO, Inc. 32 4. 失敗(と言い切るほどではないが)談


Slide 33

Slide 33 text

© ZOZO, Inc. 33 Firestoreという選択
 ● ドキュメント指向DBの設計の難しさ
 ○ マルチテナントをいい感じにすることを重視して選択したが、アプリケーションの性質上向 いていないと感じた
 ○ 慣れれば解決するかと思ったが
 ● マルチテナントはPostgreSQLなどが備えるRow Level Securityで実現可能だった
 ○ 完全に調査不足
 ● 現在PostgreSQL移行(合わせてAWS移行)を検討中
 ○ Repositoryパターンを使ってるので移行しやすい…はず…


Slide 34

Slide 34 text

© ZOZO, Inc. 34 Cloud Runという選択
 ● Datadog APMに対応していない
 ● k8sをSREチーム標準にすることが決定
 ○ SREのリソースが確保できるようになってきた


Slide 35

Slide 35 text

© ZOZO, Inc. 35 5. まとめ


Slide 36

Slide 36 text

© ZOZO, Inc. 36 まとめ
 ● FAANSはGCP, Firebaseを中心にGoで開発をしています
 ● レイヤードアーキテクチャ、コード生成などの工夫をして開発をしています
 ● 導入企業拡大中で各社の需要をヒアリングしながら具体化していく予定です
 ● それに備えてPostgreSQL移行、GKE移行などの大きな開発を予定しています
 
 
 上記に興味があるエンジニアを募集中です!


Slide 37

Slide 37 text

No content