$30 off During Our Annual Pro Sale. View Details »

Go+gRPCで作った次世代店舗の裏側

howyi
February 22, 2022

 Go+gRPCで作った次世代店舗の裏側

GeekGig 『DONUTS×Showcase Gig』〜Goでゼロから作り直した話〜
で発表したスライドです。

https://showcase-gig.connpass.com/event/235635/

howyi

February 22, 2022
Tweet

More Decks by howyi

Other Decks in Programming

Transcript

  1. confidential Go+gRPCで作った次世代店舗の裏側
 2022-02-22 GeekGig 『DONUTS×Showcase Gig』〜Goでゼロから作り直した話〜 🐔 Hayashi Takuya


  2. confidential Hayashi Takuya
 自己紹介 Showcase Gig 店内機器の開発 /連携を行うチームのエンジニア兼チームリーダーをやっています GitHub: howyi

    twitter: @howyi_lq
  3. confidential ©Showcase Gig • 次世代店舗の紹介 • 次世代店舗のシステム構成 • gRPCサーバの利用者向けSDKの用意 •

    ロッカーとの接続を行うエッジサーバについて • gRPCを採用してよかったこと 今日話すこと

  4. confidential ©Showcase Gig 次世代店舗の紹介


  5. confidential ©Showcase Gig • スマホから事前に注文&決済 • QRを読み取り、自動で開く ロッカーから非対面で受け取り The Label

    Fruit

  6. confidential ©Showcase Gig The Label Fruit
 • 店外に商品の出来上がりを通知する サイネージ •

    注文はリアルタイムでサイネージに表 示される • 受取ロッカーの各扉にディスプレイ • QRコードの読み取り後、ロッカーの扉 は専用の演出が流れる
  7. confidential ©Showcase Gig 次世代店舗のシステム構成


  8. confidential ©Showcase Gig 次世代店舗のシステム構成
 O:der Platform モバイルオーダーの基盤となる機能を提供するバック エンド 注文の永続化、支払い処理、外部サービスへの通知 等、モバイルオーダーを実装するための基盤を持つ

  9. confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 店内機器リアルタイム通信基盤 店舗内の機器とリアルタイム通信を確立するた めのバックエンド 機器の管理、認証基盤としての機能も持つ

    機器とのリアルタイム通信には gRPC Streamingを使用する 配信内容の例 • 注文の状態 • ロッカーの状態
  10. confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 Streaming
 Streaming
 ロッカー
 サイネージ


    キッチンディスプレイ 
 (調理場に注文を伝えるアプリ) 

  11. confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意


  12. confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 複数箇所からAPIを叩くため、各リポジトリに同様の コードが散在しないよう APIを利用するにあたっての最 低限の機能を提供する SDKの機能 •

    APIのprotoから生成したコード(go/gen/)以下 • 認証周りの機能 ディレクトリ構成

  13. confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 go.modがリポジトリ直下以外にある場合、 goはそのリ ポジトリをMulti-Module Repositoriesとして認識する ディレクトリ構成


  14. confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 このとき、目的のモジュールへタグを打つときは v1.0.0ではなく、go.modへの相対パスをプレフィックス に含める必要がある 今回の例だと、go/v1.0.0 のタグを打って初めて go

    get github.com/showcase-gig/sdk/go@v1.0.0 といった形でパッケージをインストールすることができ る ディレクトリ構成

  15. confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 タグをGitHubリリースした時とき に自動で go/{tag} のタグを切る ようにGitHub Actionsで設定して

    いる name: "On release" env: CI: true on: release: types: [published] jobs: go-release: name: go release runs-on: ubuntu-latest steps: - name: Set version variable id: version run: | VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") echo ::set-output name=version::$VERSION - name: checkout uses: actions/checkout@v2 - name: tag to go sdk run: | git tag go/${{ steps.version.outputs.version }} git push origin go/${{ steps.version.outputs.version }}
  16. confidential ©Showcase Gig ロッカーとの接続を行うエッジサーバについて


  17. confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 Streaming
 Streaming
 ロッカー
 サイネージ


    キッチンディスプレイ 
 (調理場に注文を伝えるアプリ) 

  18. confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 Streaming
 ロッカー


  19. confidential ©Showcase Gig ロッカーの機能
 ロッカー
 店内機器リアルタイム 通信基盤 ドアの解錠命令 
 (gRPC

    Streaming) 
 QRコードの読み取り等 (gRPC Unary)

  20. confidential ©Showcase Gig 既存のIoTロッカーとの兼ね合い
 店内機器リアルタイム 通信基盤 ロッカー
 IoTロッカー(既存のものを流用) 
 IoTロッカー


    ソフトウェア ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 🥺
 ロッカーのソフトウェアと、リアルタイム通信基盤はそもそも別の用途で作られてい たため、使用している通信技術が大きく変わっている
  21. confidential ©Showcase Gig 既存のIoTロッカーとの兼ね合い
 店内機器リアルタイム 通信基盤 ロッカー
 IoTロッカー(既存のものを流用) 
 IoTロッカー


    ソフトウェア ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 IoTロッカーとリアルタイム通信基盤を変換するサーバを新設する案 • HTTP&WebSocketのサーバとして動作し、ロッカーソフトウェアの認証を行う • 常にgRPC Streamingで基盤と接続を確立する 変換 サーバ
  22. confidential ©Showcase Gig 既存のIoTロッカーとの兼ね合い
 店内機器リアルタイム 通信基盤 ロッカー
 IoTロッカー(既存のものを流用) 
 IoTロッカー


    ソフトウェア ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 IoTロッカーとリアルタイム通信基盤を変換するサーバを新設する案 • 新規サーバ構築にあたっての基盤構築の必要性 • 今回のロッカーソフトウェア専用のサーバとなり、負債となるリスク 変換 サーバ
  23. confidential ©Showcase Gig エッジサーバの配置による解決
 店内機器リアルタイム 通信基盤 ロッカー
 IoTロッカー(既存のものを流用) 
 IoTロッカー


    ソフトウェア ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 エッジサー バ ロッカー内部に通信を仲介するエッジサーバを作ってしまう案 • 既存のIoTロッカーはlocalhostに向けて今まで通り通信してもらう • エッジサーバは通信を変換し、認証情報を付与したうえでロッカーとして振る舞う • 既存のハードウェアに入り、運用するサーバや端末が増えることはない • ロッカー <-> エッジサーバ間はローカル通信のため、認証について考える必要がない
  24. confidential ©Showcase Gig エッジサーバの開発
 ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等

    (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 エッジサー バ 必要な機能 • gRPC Streamingで基盤との常時接続を保つ • HTTPサーバとして動き、リクエストを gRPC Unaryに変換してサーバへ送信する • WebSocketサーバとして起動しgRPC Streamingのイベントを接続中のクライアントに配信する • gRPCの接続時は認証情報を付与し、サーバにはロッカーとして振る舞う • cliツールとして配布し、 IoTロッカーソフトウェアの起動時に同時に裏で起動する 店内機器リアルタイム 通信基盤 IoTロッカー
 ソフトウェア
  25. confidential ©Showcase Gig エッジサーバの開発
 • CLIアプリケーションとして動作すればいいことから、使い慣れている Goを採用 • 店内機器リアルタイム通信基盤用の SDKを使用しているため、リポジトリ内のコード量はかなり

    少なく済んだ • 簡単に各OS向けのビルドができ、ビルドしたバイナリを配布するだけでエッジデバイス上で動か せるのはGoの大きなメリット ◦ 実際、macで開発しwindowsで動かしていたが、OS毎での問題には一度も直面しなかった ビルドコマンド例 GOOS=windows GOARCH=386 go build -o edge.exe cmd/locker-edge/main.go 

  26. confidential ©Showcase Gig エッジサーバの開発
 実行時にsync.ErrGroupで • gRPCのStreaming(Subscribe) • HTTPサーバ (POST,

    WebSocket) のgoroutineを起動 eg, ctx := errgroup.WithContext(ctx) httpServer := di.NewHttpServer(cfg, logger) eg.Go(func() error { err := httpServer.Start() return err }) grpcClient := di.NewGrpcClient(cfg, logger) eg.Go(func() error { err = grpcClient.Subscribe(ctx) return err }) <-ctx.Done() // シャットダウン処理
  27. confidential ©Showcase Gig gRPCを採用してよかったこと


  28. confidential ©Showcase Gig ProtocolBuffersによる
 API定義の一元管理
 柔軟な表現が可能 gRPCを採用してよかったこと goのコード生成時にマッピングする package名 google提供のannotation機能のimport

    サービスのRPCを定義 optionでgrpc-gatewayのpathを定義 grpc-gatewayのサンプルコード StringMessageという型を定義
  29. confidential ©Showcase Gig ProtocolBuffersによる
 API定義の一元管理
 柔軟な表現が可能 コメントなども含めてドキュメントに出力することも 可能なため、 protoファイル以外の場所にパラメータの 細かい仕様などが散在する状況を

    ある程度避け られる gRPCを採用してよかったこと protobuffetを使うとこのような形で protoから APIドキュメントを生成できる
  30. confidential ©Showcase Gig gRPCのコード生成
 protoc(Protocol Buffer Compiler)によるコード 生成が手厚い gRPCを採用してよかったこと 公式でコード生成をサポートしている言語

  31. confidential ©Showcase Gig gRPCのコード生成
 protoc(Protocol Buffer Compiler)によるコード 生成が手厚い APIを利用するにあたって書くコードが大幅に少 なく済み、かつ型安全になる

    社内ではprotoから複数のプログラミング言語に 向けてのSDKを自動生成するように ◦ PHP/Go/Dart/Kotlin/JavaScript ◦ https://note.com/scg_tech/n/n45c13047c648 gRPCを採用してよかったこと
  32. confidential ©Showcase Gig まとめ


  33. confidential ©Showcase Gig まとめ
 • まずサーバを作るという判断をせず、他の方法でも解決できないか考える • Goの用途は幅広く、並行処理も書きやすいのでエッジサーバなどの用途でも便利 • gRPCはコード生成も手厚く、リアルタイム通信も使いやすい

    ◦ ブラウザの場合は直接利用できないが、 grpc-webなどの手段で対応可能
  34. confidential ©Showcase Gig おわり