Slide 1

Slide 1 text

Smart Store リファレンスアーキテクチャ Deep Dive! @Tokyo, Japan

Slide 2

Slide 2 text

About Me 三宅 和之 @kazuyukimiyake 株式会社ゼンアーキテクツ CTO Microsoft MVP Vue.js ⽇本ユーザーグループ運営メンバー PaaSがかりの部屋(Blog): https://k-miyake.github.io/blog/

Slide 3

Slide 3 text

Smart Store ビジネスモデル ⽇本マイクロソフトが提唱する次世代店舗モデル 発表記事 リファレンスアーキテクチャ(OSS) リファレンスアーキテクチャに基づくサンプル実装をOSSで公開 https://github.com/intelligent-retail/smart-store サンプル実装「Smart Box」

Slide 4

Slide 4 text

Smart Store について Special Guest: Yoshifumi Okada (Microsoft)

Slide 5

Slide 5 text

アーキテクチャ全体像

Slide 6

Slide 6 text

アーキテクチャの⽅向性・狙い マイクロサービス ユースケースによって使いたいサービスは異なるはず サーバーレス できるだけシンプルな基盤にしたい スケーラビリティを柔軟に調整しなければならない リアルタイム性の重視 情報の鮮度が重要なユースケースが多い

Slide 7

Slide 7 text

Deep Dive - Agenda 1. モバイルデバイスへのプッシュ通知 2. サーバレスAPI と CQRS 3. リアルタイムWebによる管理UI 4. マイクロサービスのデプロイ

Slide 8

Slide 8 text

Deep Dive 1 - モバイルデバイスへのプッシュ通知 contributor: @masatoru

Slide 9

Slide 9 text

モバイルデバイスへのプッシュ通知 モバイルアプリは、 Xamarin.Forms で実装 プッシュ通知のサービスに App Center を利⽤

Slide 10

Slide 10 text

App Center + Firebase の設定 Just 7 Steps!!

Slide 11

Slide 11 text

Xamarin.Forms での App Center Push の実装 「Azure Notificatoin Hubsに⽐べたら圧倒的に楽ちん」 by @masatoru

Slide 12

Slide 12 text

#Xamarinはいいぞ

Slide 13

Slide 13 text

Deep Dive 2 - サーバレスAPI と CQRS contributor: @shibayan

Slide 14

Slide 14 text

サーバレスAPI と CQRS サーバレスによる在庫管理の実装 Azure Functions (V2) によるサーバレスAPI CQRS によるバックエンド (Cosmos DB Change Feed)

Slide 15

Slide 15 text

Azure Functions による CQRS 実装 CQRS を実現するためには 3つのFunction が必要 コマンド: StockService.StockCommand/CommandFunction.cs 同期: StockService.StockProcessor/ChangeFeedFunction.cs クエリー: StockService.StockQuery/QueryFunction.cs 実装上のポイント Http Trigger のJSONモデルバインディングで⼀部問題があった(最終的に解消) Cosmos DB SDK は プレビューでも 3.x を使⽤した(すべき) Cosmos DB Trigger の leaseコレクション の扱い(要注意) Change Feed の同期を速くするために FeedPollDelay = 500 を追加で設定

Slide 16

Slide 16 text

CQRS の性能検証 Visual Studio Load Test を使って、約1万req/分(秒間 196 req)まで負荷を上げた 適切なスループットがあれば劣化はしない(平均処理時間: 397ms、中央値: 146ms)

Slide 17

Slide 17 text

Application Insights による分散トレーシング マイクロサービスで実装する場合、分散トレーシングが必須となる 実装 起点となる Command で ActivityId をセット // 追跡⽤の ActivityId をセット document.ActivityId = Activity.Current?.Id; _telemetryClient.TrackTrace("Begin Stock Command", new Dictionary { { "ActivityId", document.ActivityId } }); 同期処理を⾏う Processor は、コレクションでバインドされてくるため、カスタマイ ズが必要 // Application Insights に通知 foreach (var document in documents) { _telemetryClient.TrackTrace("End Stock Processor", new Dictionary { { "ActivityId", document.ActivityId } }); }

Slide 18

Slide 18 text

Deep Dive 3 - リアルタイムWebによる管理UI contributor: @shibayan, @kazuyukimiyake

Slide 19

Slide 19 text

リアルタイムWebによる管理UI SignalR Service によるリアルタイム通知 Vue.js による画⾯実装

Slide 20

Slide 20 text

SignalR Service のServerless Mode (Backend) 開発中に SignalR Service に Serverless Mode が登場! -> Hubの実装が不要に Azure Functions 側は SignalR Output Bind を使って更新を通知する var signalRMessages = binder.Bind>(new SignalRAttribute { ConnectionStringSetting = "SignalRConnection", HubName = "monitor" }); // 変更通知を SignalR で送信する foreach (var document in documents) { foreach (var item in document.Items) { await signalRMessages.AddAsync(new SignalRMessage { Target = "update", Arguments = new object[] { document.TerminalCode, item.ItemCode } }); } }

Slide 21

Slide 21 text

SignalR Service のServerless Mode クライアント側は signalr.js を使って更新イベントを待ち受ける mounted: async function () { // 初回のデータを取得する this.init(); // SignalRとコネクションを確⽴する const conn = await axios.post(`${server.endPoint}/api/negotiate`, null, getAxiosConfig()); const info = conn.data; const options = { accessTokenFactory: () => info.accessToken }; const connection = new signalR.HubConnectionBuilder() .withUrl(info.url, options) .configureLogging(signalR.LogLevel.Information) .build(); // Azure Functions から update が呼ばれた時に画⾯を更新 connection.on('update', this.update); }

Slide 22

Slide 22 text

Vue.js でのリアルタイム描画 SignalR と Vue.js のデータバインディングの相性はバッチリ js側は基本的にオブジェクトを更新するだけ 画⾯は、バインディングとCSSトランジションを書いておけばOK

{{item.quantity}}

{{item.itemName}}

Slide 23

Slide 23 text

Deep Dive 4 - マイクロサービスのデプロイ contributor: @dz_

Slide 24

Slide 24 text

マイクロサービスのデプロイ サーバーレスで実装したため、⼀貫性のあるデプロイを作り込む必要があった (コンテナオーケストレーターのような仕組みがないため) ARM Template 実装例

Slide 25

Slide 25 text

ARM Template の開発 ポイント メンテナンス性を考慮し、Linked template を利⽤ マイクロサービス単位毎にテンプレートを分割 デプロイ実⾏時は、サービスの組み合わせをまとめた親テンプレートで実⾏ App Service デプロイ後に Run From Package を使って Function App も⾃動デプロ イ デプロイの実⾏コマンドは基本的にこれだけ(変数の設定などは除く) az group deployment create \ --resource-group ${RESOURCE_GROUP} \ --template-uri ${TEMPLATE_URL}/template.json \ --parameters ${TEMPLATE_URL}/parameters.json \ --parameters \ prefix=${PREFIX} \ stockServiceSqlServerAdminPassword=${STOCK_SERVICE_SQL_SERVER_ADMIN_PASSWORD}

Slide 26

Slide 26 text

今⽇お話したこと 1. モバイルデバイスへのプッシュ通知 2. サーバレスAPI と CQRS 3. リアルタイムWebによる管理UI 4. マイクロサービスのデプロイ

Slide 27

Slide 27 text

https://github.com/intelligent-retail/smart-store

Slide 28

Slide 28 text

ご清聴ありがとうございました︕