Slide 1

Slide 1 text

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


Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

confidential ©Showcase Gig ● 次世代店舗の紹介 ● 次世代店舗のシステム構成 ● gRPCサーバの利用者向けSDKの用意 ● ロッカーとの接続を行うエッジサーバについて ● gRPCを採用してよかったこと 今日話すこと


Slide 4

Slide 4 text

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


Slide 5

Slide 5 text

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


Slide 6

Slide 6 text

confidential ©Showcase Gig The Label Fruit
 ● 店外に商品の出来上がりを通知する サイネージ ● 注文はリアルタイムでサイネージに表 示される ● 受取ロッカーの各扉にディスプレイ ● QRコードの読み取り後、ロッカーの扉 は専用の演出が流れる

Slide 7

Slide 7 text

confidential ©Showcase Gig 次世代店舗のシステム構成


Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 店内機器リアルタイム通信基盤 店舗内の機器とリアルタイム通信を確立するた めのバックエンド 機器の管理、認証基盤としての機能も持つ 機器とのリアルタイム通信には gRPC Streamingを使用する 配信内容の例 ● 注文の状態 ● ロッカーの状態

Slide 10

Slide 10 text

confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 Streaming
 Streaming
 ロッカー
 サイネージ
 キッチンディスプレイ 
 (調理場に注文を伝えるアプリ) 


Slide 11

Slide 11 text

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


Slide 12

Slide 12 text

confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 複数箇所からAPIを叩くため、各リポジトリに同様の コードが散在しないよう APIを利用するにあたっての最 低限の機能を提供する SDKの機能 ● APIのprotoから生成したコード(go/gen/)以下 ● 認証周りの機能 ディレクトリ構成


Slide 13

Slide 13 text

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


Slide 14

Slide 14 text

confidential ©Showcase Gig gRPCサーバの利用者向けSDKの用意
 このとき、目的のモジュールへタグを打つときは v1.0.0ではなく、go.modへの相対パスをプレフィックス に含める必要がある 今回の例だと、go/v1.0.0 のタグを打って初めて go get github.com/showcase-gig/sdk/[email protected] といった形でパッケージをインストールすることができ る ディレクトリ構成


Slide 15

Slide 15 text

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 }}

Slide 16

Slide 16 text

confidential ©Showcase Gig ロッカーとの接続を行うエッジサーバについて


Slide 17

Slide 17 text

confidential ©Showcase Gig 次世代店舗のシステム構成
 店内機器リアルタイム 通信基盤 Streaming
 Streaming
 ロッカー
 サイネージ
 キッチンディスプレイ 
 (調理場に注文を伝えるアプリ) 


Slide 18

Slide 18 text

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


Slide 19

Slide 19 text

confidential ©Showcase Gig ロッカーの機能
 ロッカー
 店内機器リアルタイム 通信基盤 ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)


Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

confidential ©Showcase Gig エッジサーバの開発
 ドアの解錠命令 
 (gRPC Streaming) 
 QRコードの読み取り等 (gRPC Unary)
 QRコードの読み取り等 (HTTP POST)
 ドアの解錠命令 (WebSocket) 
 エッジサー バ 必要な機能 ● gRPC Streamingで基盤との常時接続を保つ ● HTTPサーバとして動き、リクエストを gRPC Unaryに変換してサーバへ送信する ● WebSocketサーバとして起動しgRPC Streamingのイベントを接続中のクライアントに配信する ● gRPCの接続時は認証情報を付与し、サーバにはロッカーとして振る舞う ● cliツールとして配布し、 IoTロッカーソフトウェアの起動時に同時に裏で起動する 店内機器リアルタイム 通信基盤 IoTロッカー
 ソフトウェア

Slide 25

Slide 25 text

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 


Slide 26

Slide 26 text

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() // シャットダウン処理

Slide 27

Slide 27 text

confidential ©Showcase Gig gRPCを採用してよかったこと


Slide 28

Slide 28 text

confidential ©Showcase Gig ProtocolBuffersによる
 API定義の一元管理
 柔軟な表現が可能 gRPCを採用してよかったこと goのコード生成時にマッピングする package名 google提供のannotation機能のimport サービスのRPCを定義 optionでgrpc-gatewayのpathを定義 grpc-gatewayのサンプルコード StringMessageという型を定義

Slide 29

Slide 29 text

confidential ©Showcase Gig ProtocolBuffersによる
 API定義の一元管理
 柔軟な表現が可能 コメントなども含めてドキュメントに出力することも 可能なため、 protoファイル以外の場所にパラメータの 細かい仕様などが散在する状況を ある程度避け られる gRPCを採用してよかったこと protobuffetを使うとこのような形で protoから APIドキュメントを生成できる

Slide 30

Slide 30 text

confidential ©Showcase Gig gRPCのコード生成
 protoc(Protocol Buffer Compiler)によるコード 生成が手厚い gRPCを採用してよかったこと 公式でコード生成をサポートしている言語

Slide 31

Slide 31 text

confidential ©Showcase Gig gRPCのコード生成
 protoc(Protocol Buffer Compiler)によるコード 生成が手厚い APIを利用するにあたって書くコードが大幅に少 なく済み、かつ型安全になる 社内ではprotoから複数のプログラミング言語に 向けてのSDKを自動生成するように ○ PHP/Go/Dart/Kotlin/JavaScript ○ https://note.com/scg_tech/n/n45c13047c648 gRPCを採用してよかったこと

Slide 32

Slide 32 text

confidential ©Showcase Gig まとめ


Slide 33

Slide 33 text

confidential ©Showcase Gig まとめ
 ● まずサーバを作るという判断をせず、他の方法でも解決できないか考える ● Goの用途は幅広く、並行処理も書きやすいのでエッジサーバなどの用途でも便利 ● gRPCはコード生成も手厚く、リアルタイム通信も使いやすい ○ ブラウザの場合は直接利用できないが、 grpc-webなどの手段で対応可能

Slide 34

Slide 34 text

confidential ©Showcase Gig おわり